RLS в БСП в производительном варианте настраивается не в ролях, а в модуле менеджера объекта: вы описываете текст ограничения в процедуре ПриЗаполненииОграниченияДоступа, регистрируете объект в УправлениеДоступомПереопределяемый.ПриЗаполненииСписковСОграничениемДоступа, добавляете его в определяемые типы владельцев ключей доступа и ставите в ролях короткий шаблон #ДляОбъекта или #ДляРегистра. После этого подсистема «Управление доступом» рассчитывает ключи доступа и проверяет права через них.
Пропустите хотя бы один шаг — и получите либо ошибку при открытии списка, либо, что хуже, пользователь будет видеть лишние данные. Ниже — пошаговая инструкция для ссылочных объектов и регистров сведений и чек-лист диагностики «лишней видимости».
Как устроен производительный вариант RLS
Включается он настройкой «Ограничивать доступ на уровне записей» с универсальным режимом. Отличие от классического варианта:
| Классический RLS | Производительный (универсальный) | |
|---|---|---|
| Где описано ограничение | Длинные шаблоны в каждой роли | Текст в модуле менеджера объекта |
| Как проверяется | Условие с подзапросами к значениям доступа | Через рассчитанные ключи доступа |
| Шаблон в роли | Параметризованный под объект | Унифицированный ДляОбъекта / ДляРегистра |
| Поддержка | Правки во многих ролях | Правка в одном месте |
Язык ограничения — подмножество языка запросов с собственными конструкциями: РазрешитьЧтениеИзменение, ГДЕ, ЗначениеРазрешено(), ПрисоединитьДополнительныеТаблицы и другими. Полное описание — в комментарии к ПриЗаполненииСписковСОграничениемДоступа в общем модуле УправлениеДоступомПереопределяемый вашей версии БСП. Я всегда открываю его перед работой: синтаксис расширялся от версии к версии.

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




