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