В механизме 1С:Предприятие 8 Row Level Security (RLS) является мощным инструментом для разграничения доступа на уровне отдельных записей базы данных. Однако при его настройке программисты часто сталкиваются с ситуацией, когда написанное условие просто «не срабатывает», и пользователь продолжает видеть весь список данных. Рассмотрим на примере конфигурации «Управление торговлей 11.3», как правильно ограничить доступ к справочнику Партнеры, основываясь на данных из карточки текущего пользователя.
Разберем ситуацию: в справочнике Пользователи добавлен дополнительный реквизит Партнер. Задача — сделать так, чтобы текущий пользователь видел только того партнера, который указан у него в карточке. Автор темы попытался использовать следующий код в роли для ограничения доступа на чтение справочника Партнеры:
Партнеры ИЗ Справочник.Пользователи КАК Пользователи
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Партнеры КАК Партнеры
ПО (Партнеры.Ссылка = Пользователи.Партнер)
ГДЕ Пользователи.Ссылка = &ТекущийПользователь
Этот код не сработал, так как структура запроса была нарушена. В тексте RLS для конкретного объекта (в данном случае справочника Партнеры) система ожидает, что основным объектом выборки будет сам этот справочник. Проанализируем, почему ЛЕВОЕ СОЕДИНЕНИЕ здесь не подходит: при левом соединении, если условие в ПО не выполняется, записи из левой таблицы (Пользователи) все равно остаются в выборке, а поля правой таблицы (Партнеры) заполняются значениями NULL. В контексте RLS это часто приводит к непредсказуемому поведению или полному игнорированию фильтра.
Для того чтобы ограничение работало корректно через связи таблиц, необходимо использовать ВНУТРЕННЕЕ СОЕДИНЕНИЕ. Это гарантирует, что в выборку попадут только те записи справочника Партнеры, для которых нашлось соответствие в справочнике Пользователи по заданному условию. Рассмотрим исправленный вариант запроса:
Партнеры ИЗ Справочник.Партнеры КАК Партнеры
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Пользователи КАК Пользователи
ПО Партнеры.Ссылка = Пользователи.Партнер
ГДЕ Пользователи.Ссылка = &ТекущийПользователь
В этом примере мы четко указываем системе: «Выбери только тех партнеров, ссылка которых совпадает с реквизитом Партнер у того пользователя, чей сеанс сейчас активен (&ТекущийПользователь)». Это надежный способ, который работает на уровне СУБД.
В современных версиях платформы 1С v8.3 и типовых конфигурациях (УТ, ERP, КА) можно использовать более лаконичный синтаксис. Вместо сложных соединений мы можем напрямую сравнить ссылку партнера с реквизитом параметра сеанса. Выясним, как это реализовать наиболее эффективно:
ГДЕ Ссылка = ВЫРАЗИТЬ(&ТекущийПользователь КАК Справочник.Пользователи).Партнер
Почему важно использовать ВЫРАЗИТЬ? Параметр сеанса &ТекущийПользователь часто имеет составной тип (например, может содержать ссылку на Пользователи или ВнешниеПользователи). Используя ВЫРАЗИТЬ, мы помогаем оптимизатору запросов 1С заранее определить, к какой таблице будет идти обращение, что предотвращает лишние проверки и повышает производительность системы.
Однако помните: обращение через точку в RLS порождает неявное LEFT JOIN на уровне SQL. Если вы используете длинные цепочки (например, &ТекущийПользователь.Партнер.ОсновнойМенеджер.Подразделение), это может значительно замедлить работу динамических списков.
Если вы внедрили один из предложенных выше вариантов, но пользователь все равно видит лишние записи, проанализируем неочевидные причины:
Роль1 с ограничением и Роль2 (например, «Просмотр всех партнеров» или «Полные права»), система разрешит доступ. Достаточно ОДНОЙ роли без RLS, чтобы ограничение в других ролях перестало иметь смысл. Проверьте все роли, назначенные пользователю.ПривилегированныйРежимУстановить(Истина), или запрос в модуле с флагом «Привилегированный», то RLS применяться не будет.#ПоЗначениям. Это позволяет управлять доступом через пользовательский интерфейс (Профили групп доступа), не прибегая к изменению конфигурации.Для успешной настройки ограничений выполним следующие шаги:
ВНУТРЕННЕЕ СОЕДИНЕНИЕ, и у пользователя в карточке реквизит Партнер не заполнен, он не увидит вообще ни одной записи. Если нужно разрешить просмотр всех при незаполненном реквизите, логику запроса придется усложнить.Таким образом, мы выяснили, что наиболее стабильным и читаемым решением для ограничения доступа к партнерам является использование прямого сравнения с типизированным параметром сеанса или корректное использование внутреннего соединения. Проанализируйте структуру прав вашего пользователя и убедитесь, что никакие другие роли не перекрывают ваши настройки RLS.