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