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