Настройка RLS в 1С: Почему при скрытии колонки в списке видны чужие документы и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При настройке ограничений доступа на уровне записей (RLS) в «1С:Предприятии 8» разработчики часто сталкиваются с неочевидным поведением системы: ограничение по определенному реквизиту (например, по ответственному лицу или организации) прекрасно работает, пока соответствующая колонка выведена на форму. Но стоит пользователю скрыть эту колонку через настройки формы, как в динамическом списке внезапно отображаются абсолютно все документы, включая чужие.

В этой статье мы подробно разберем, почему платформа ведет себя подобным образом, изучим механизмы работы динамических списков под управлением RLS и пошагово исправим эту ошибку на конкретном примере.

Выясняем причину: как платформа 1С оптимизирует запросы

Давайте проанализируем ситуацию. Предположим, мы создали новый документ в конфигураторе и добавили в него реквизит Ответственный с типом ссылки на справочник пользователей. Для новой роли мы прописали простое ограничение на чтение:

ГДЕ Ответственный = &ТекущийПользователь

Когда пользователь открывает список документов, платформа генерирует SQL-запрос к базе данных. Особенность работы динамических списков заключается в жесткой оптимизации. Если колонка Ответственный выведена на форму, платформа запрашивает это поле из базы данных, видит наложенное на него ограничение RLS и применяет соответствующий отбор. В итоге пользователь видит только свои документы.

Но что происходит, когда пользователь отключает видимость колонки Ответственный через команду «Изменить форму»? Платформа понимает, что выводить это поле на экран больше не нужно. С целью экономии трафика и ресурсов СУБД, поле Ответственный полностью исключается из SQL-запроса.

Поскольку поле больше не запрашивается, условие RLS, жестко привязанное к этому конкретному полю, игнорируется платформой. Ограничение просто перестает накладываться на уровне СУБД, и пользователь получает доступ ко всем строкам таблицы в списке. При этом при попытке открыть «чужой» документ RLS сработает корректно (так как форма объекта всегда запрашивает все реквизиты), но сам факт видимости чужих документов в списке является серьезной брешью в безопасности.

Пошаговое решение проблемы в Конфигураторе

Чтобы ограничение доступа гарантированно отрабатывало независимо от настроек формы и видимости колонок пользователем, нам необходимо правильно перераспределить ограничения по полям в конфигурации.

Разберем по шагам, как решить эту задачу:

  1. Откроем Конфигуратор и перейдем к роли, в которой настроено наше ограничение доступа.
  2. Найдем в списке объектов наш документ и перейдем на вкладку Шаблоны ограничений или сразу в таблицу Ограничения доступа к данным на право Чтение.
  3. Обратим внимание на колонку Поля. Если там выбрано конкретное поле Ответственный, то именно это и приводит к ошибке. Нам необходимо применить ограничение ко всей записи в целом.
  4. Изменим настройку: в колонке Поля укажем значение <Прочие поля>. Строка ограничения должна выглядеть следующим образом:
    
    ТекущаяТаблица ИЗ #ТекущаяТаблица КАК ТекущаяТаблица
    ГДЕ Ответственный = &ТекущийПользователь
    
  5. Сохраним конфигурацию базы данных и проверим результат. Теперь, даже если пользователь скроет колонку с ответственным, платформа применит условие RLS к «прочим полям» (к которым относятся все остальные реквизиты документа, оставшиеся в списке) и скроет чужие записи.

Важный паттерн: Избавляемся от проблемы «<Объект не найден>»

Настройка ограничения по <Прочие поля> полностью решает проблему отображения лишних строк в динамических списках, но на практике она может породить другую неприятность. Если мы полностью закроем чтение документа для чужих пользователей, то во всех связанных отчетах, журналах или других документах, где есть ссылки на эти скрытые документы, пользователи увидят пугающую надпись «<Объект не найден>».

Чтобы избежать появления битых ссылок и сохранить эстетичный вид интерфейса, в профессиональной разработке применяется стандартный паттерн разделения прав на Чтение. Мы настраиваем не одну, а две строки ограничений для права Чтение в роли:

Строка 1 (Доступ к ключевым полям для представления ссылки):

Строка 2 (Ограничение доступа к содержанию документа):

При такой схеме пользователь сможет видеть красивое представление чужих документов в отчетах, но при попытке открыть форму документа или прочитать его детальное содержимое (табличные части, суммы, контрагентов) система выдаст сообщение о нарушении прав доступа.

Оптимизация производительности: Индексация полей RLS

При работе с механизмами RLS критически важно помнить о производительности СУБД. Когда платформа накладывает условия RLS на лету, она модифицирует исходные SQL-запросы, добавляя в них подзапросы и соединения. Если база данных содержит сотни тысяч документов, неоптимальный RLS может привести к колоссальным задержкам при открытии списков.

Проанализируем ситуацию: в нашем условии фигурирует поле Ответственный. Если по этому полю в базе данных нет индекса, СУБД будет вынуждена выполнять полное сканирование таблицы (Full Table Scan) при каждом обращении к списку документов.

Решение чрезвычайно простое, но обязательное: в свойствах реквизита Ответственный нашего документа в Конфигураторе необходимо установить свойство Индексировать в значение Индексировать или Индексировать с доп. упорядочиванием. Наличие индекса позволит СУБД мгновенно отфильтровывать документы по текущему пользователю.

Современный подход: Производительный RLS в БСП

Если мы ведем разработку в современных конфигурациях (таких как «Бухгалтерия предприятия 3.0», «ERP Управление предприятием» или «Управление торговлей 11»), классический «ручной» RLS в ролях практически не используется. В Библиотеке стандартных подсистем (БСП) реализован так называемый Производительный режим RLS.

В этом режиме платформа не строит тяжелые запросы на лету. Вместо этого права доступа рассчитываются предварительно при записи объектов и кэшируются в специальных служебных регистрах сведений (например, РегистрСведений.КлючиДоступаКДокументам). При открытии списка СУБД просто быстро соединяет таблицу документов с таблицей разрешенных ключей для текущего пользователя.

При разработке в таких конфигурациях логика RLS описывается программно в модуле менеджера объекта. Рассмотрим пример настройки доступа по ответственному через БСП:


Процедура ПриЗаполненииОграниченияДоступа(Ограничение) Экспорт
    
    Ограничение.Текст =
        "РазрешитьЧтениеИзменение ГДЕ ЗначениеРазрешено(Ответственный)";
        
КонецПроцедуры

После добавления данного кода в модуль менеджера документа и обновления служебных данных (через запуск обновления конфигурации или запуск специальной обработки БСП) система автоматически сформирует все нужные шаблоны ограничений в ролях и обеспечит максимальную скорость работы динамических списков без уязвимостей безопасности.

← На главную