Ограничение прав доступа на уровне записей (RLS) в современных конфигурациях 1С, работающих на базе БСП (Библиотека стандартных подсистем), — это сложная архитектурная задача. Особенно остро проблема встает, когда требуется не просто запретить редактирование, а полностью скрыть определенные элементы справочника Номенклатура от глаз пользователя. Рассмотрим, с какими трудностями мы можем столкнуться, разберем причины возникновения ошибок и проанализируем наиболее эффективные пути решения этой задачи.
В современных версиях БСП используется так называемый «Производительный режим» управления доступом. Его ключевая особенность заключается в том, что система не вычисляет права «на лету» при каждом запросе, а использует заранее рассчитанные данные, хранящиеся в специальных регистрах (например, РегистрСведений.КлючиДоступаКОбъектам). Когда мы пытаемся ограничить чтение базового справочника, такого как Номенклатура, мы вмешиваемся в работу фундаментального узла системы.
Разберем типичную ситуацию: вы настроили ограничения, и на первый взгляд все работает — в списке справочника лишние позиции исчезли. Однако при попытке найти товар в документе или ввести его название в поле ввода, система выдает критическую ошибку: «У пользователя недостаточно прав на исполнение операции над базой данных». Выясним, почему это происходит.
Проанализируем работу платформы в момент интерактивного подбора. В большинстве типовых решений (УНФ, ERP, КА) для справочника Номенклатура переопределен стандартный поиск. Он выполняется в процедуре ОбработкаПолученияДанныхВыбора в модуле менеджера справочника.
Основная проблема заключается в том, что разработчики типовых конфигураций часто используют прямые запросы к базе данных для ускорения поиска, но при этом опускают ключевое слово РАЗРЕШЕННЫЕ. Логика проста: номенклатура считается базовой нормативно-справочной информацией (НСИ), которая должна быть доступна всем хотя бы на чтение. Рассмотрим пример проблемного кода, который часто встречается в типовых решениях:
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование ПОДОБНО &ТекстЗапроса";
Запрос.УстановитьПараметр("ТекстЗапроса", "%" + Параметры.СтрокаПоиска + "%");
// В этот момент, если в выборку попадает хоть один скрытый элемент,
// платформа вызовет исключение, так как модификатор РАЗРЕШЕННЫЕ отсутствует.
ДанныеВыбора = Запрос.Выполнить().Выгрузить();
КонецПроцедуры
Чтобы исправить эту ситуацию, нам необходимо использовать механизм расширений конфигурации. Мы должны перехватить выполнение этой процедуры и добавить в текст запроса заветное слово РАЗРЕШЕННЫЕ. Однако, проанализировав конфигурацию, мы увидим, что таких мест могут быть сотни: отчеты, обработки подбора, динамические списки с произвольными запросами и экспортные функции в общих модулях.
Посмотрим на ситуацию с точки зрения пользователя, который открывает старый документ (например, «Заказ покупателя»), в котором выбрана номенклатура, теперь ставшая для него запрещенной. Вместо понятного названия товара он увидит надпись «Объект не найден <...>».
Это не просто эстетическая проблема. Проанализируем последствия:
Строка.Номенклатура.СтавкаНДС), система выдаст ошибку прав доступа, и документ не будет проведен.Часто задача скрыть номенклатуру продиктована желанием защитить интеллектуальную собственность — состав изделия. Рассмотрим более рациональный путь, предложенный в обсуждении. Вместо того чтобы «ломать» всю систему, ограничивая базовый справочник Номенклатура, сосредоточимся на справочнике Спецификации.
Спецификации значительно проще ограничивать по следующим причинам:
Если же скрыть номенклатуру жизненно необходимо, разберем вариант с добавлением собственного признака доступа. Допустим, мы добавили в справочник реквизит СекретнаяНоменклатура (тип Булево).
Чтобы это заработало в производительном режиме RLS, нам потребуется выполнить следующие шаги:
УправлениеДоступомПереопределяемый).Рассмотрим пример кода, который может потребоваться для принудительного обновления прав после программного изменения реквизита:
// Пример вызова обновления ключей доступа для конкретного объекта
УправлениеДоступом.ОбновитьКлючиДоступа(СсылкаНаНоменклатуру);
Проанализировав все за и против, мы приходим к выводу, что полное скрытие номенклатуры на чтение в типовых решениях — это крайняя мера, ведущая к значительным затратам на поддержку.
Рекомендуемая стратегия действий:
ОбработкаПолученияДанныхВыбора и тщательной проверке всех значимых отчетов на наличие модификатора РАЗРЕШЕННЫЕ.Помните, что использование RLS на чтение для справочников с десятками тысяч записей неизбежно приведет к замедлению работы системы, так как SQL-серверу придется выполнять сложные соединения с таблицами прав при каждом обращении к данным.