Как открыть отчет в привилегированном режиме, если у пользователя нет прав на данные?

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

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

Почему не работает привилегированный режим в ПриКомпоновкеРезультата

Основная причина заключается в том, что ПриКомпоновкеРезультата выполняется в контексте, где система уже инициализировала механизм компоновки данных. Если права пользователя ограничены, то на этапе компиляции запроса СКД платформа автоматически применяет ограничения доступа к таблицам базы данных. Установка привилегированного режима внутри этого метода не отменяет уже наложенные ограничения, так как план выполнения запроса был сформирован до того, как вы сменили режим доступа.

Решение 1: Вынос логики получения данных в привилегированный модуль

Самый надежный способ обойти ограничения прав — это не позволять СКД обращаться к «закрытым» объектам напрямую. Мы можем подготовить данные заранее, используя привилегированный контекст. Для этого выполним следующие шаги:

  1. Создайте серверный модуль, у которого в свойствах установлен флажок Привилегированный.
  2. В этом модуле опишите функцию, которая будет выполнять запрос к данным и возвращать результат в виде ТаблицаЗначений.

Пример реализации функции в модуле:


Функция ПолучитьДанныеДляОтчета(ПараметрыОтчета) Экспорт
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ * ИЗ Документ.ВашДокумент КАК Док";
    Возврат Запрос.Выполнить().Выгрузить();
КонецФункции

Теперь в событии ПриКомпоновкеРезультата вы вызываете эту функцию, получаете таблицу и передаете её в качестве внешнего набора данных. Это позволяет «подсунуть» СКД готовые данные, не заставляя её самостоятельно обращаться к таблицам, на которые у пользователя нет прав.

Решение 2: Использование внешних наборов данных

Этот метод является наиболее правильным с архитектурной точки зрения. Вы не «обманываете» систему, а используете стандартный механизм работы с внешними данными.

  1. Откройте схему компоновки данных и добавьте в поле Наборы данных новый элемент: Набор данных - объект.
  2. Укажите имя набора данных, например, ДанныеОтчета.
  3. В модуле отчета, внутри метода ПриКомпоновкеРезультата, установите этот набор данных:

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    // Получаем данные в привилегированном режиме
    Данные = МойПривилегированныйМодуль.ПолучитьДанныеДляОтчета(Параметры);
    
    // Передаем данные в СКД
    ВнешниеНаборы = Новый Структура("ДанныеОтчета", Данные);
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    Макет = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(Макет, ВнешниеНаборы, ДанныеРасшифровки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры

Рекомендации по безопасности

Несмотря на то что использование привилегированного режима решает задачу отображения данных, мы рекомендуем также рассмотреть настройку RLS (ограничение доступа на уровне записей). Использование привилегированного режима — это потенциальная «дыра» в безопасности, так как он предоставляет полные права на весь код, выполняемый внутри блока. Использование шаблонов ограничений RLS позволяет системе автоматически фильтровать данные, отображая пользователю только то, что ему разрешено, без необходимости переводить исполнение кода в привилегированный режим.

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

← На главную