Как в отчете СКД программно обойти ограничения прав доступа (RLS)?

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

В практике разработки на платформе 1С часто возникает ситуация, когда пользователю с ограниченными правами доступа (RLS) необходимо сформировать отчет, содержащий данные, к которым у него в обычном режиме нет доступа. Например, менеджер видит только своих контрагентов, но специализированный аналитический отчет должен показать ему общие итоги по всем партнерам, чьи наименования начинаются на определенную букву. При попытке стандартного формирования такого отчета система выдает ошибку: "У пользователя недостаточно прав на исполнение операции над базой данных". Разберем подробно, как решить эту задачу, сохранив безопасность системы и обеспечив корректное получение данных.

Причина возникновения ошибки при работе с СКД

Проблема кроется в том, что СистемаКомпоновкиДанных (СКД) при выполнении запроса в контексте обычного пользователя автоматически добавляет в текст запроса условия, прописанные в правилах RLS. Даже если мы используем ключевое слово РАЗРЕШЕННЫЕ, система просто скроет недоступные записи, а если попытаемся обойтись без него при строгих ограничениях — получим отказ в доступе на уровне СУБД. Вызов метода ПроцессорКомпоновки.Следующий() инициирует фактическое получение данных, и именно в этот момент платформа блокирует операцию.

Решение 1: Использование привилегированного режима на сервере

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

Проанализируем алгоритм, который должен выполняться в таком модуле:

  1. Инициализация схемы компоновки данных.
  2. Настройка компоновщика макета.
  3. Выполнение запроса и генерация результата в табличный документ.
  4. Возврат готового результата на клиент.

Пример программного кода для реализации этого подхода:


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

Важно помнить, что при выполнении метода КомпоновщикМакета.Выполнить() в привилегированном режиме платформа генерирует текст запроса без условий RLS, что и позволяет получить все данные.

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

Рассмотрим ситуацию, когда отчет сложный и мы хотим использовать возможности СКД по группировке и оформлению, но данные должны быть получены "в обход". В этом случае мы можем подготовить данные заранее в виде ТаблицыЗначений. Выполним запрос в привилегированном модуле обычным объектом Запрос, выгрузим результат в таблицу и передадим её в СКД как внешний набор данных.

Посмотрим на пример реализации этого метода:


// Получаем данные в привилегированном режиме
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка, Наименование ИЗ Справочник.Контрагенты ГДЕ Наименование ПОДОБНО ""баранов%""";
ТаблицаДанных = Запрос.Выполнить().Выгрузить();

// Передаем таблицу в СКД
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("НаборДанных1", ТаблицаДанных);

ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных);

Этот метод считается крайне надежным, так как СКД вообще не обращается к базе данных напрямую, а значит, механизмы RLS не могут вмешаться в процесс выборки. Однако стоит учитывать объем данных: передача огромных таблиц значений между сервером и клиентом может негативно сказаться на производительности.

Решение 3: Манипуляция параметрами сеанса (С осторожностью)

Существует альтернативный путь, основанный на изменении значения параметра сеанса, который отвечает за использование RLS в конфигурации (например, ИспользоватьОграничениеПравДоступа). Мы можем временно установить его в Ложь, выполнить формирование отчета и вернуть в Истина.

Внимание: Это "грязный" метод, который несет в себе риски безопасности. Рассмотрим, как минимизировать эти риски с помощью конструкции Попытка...Исключение, чтобы в случае программного сбоя права пользователя не остались расширенными навсегда.


Попытка
    ПараметрыСеанса.ИспользоватьОграничениеПравДоступа = Ложь;
    // Код формирования отчета
    // ...
    ПараметрыСеанса.ИспользоватьОграничениеПравДоступа = Истина;
Исключение
    ПараметрыСеанса.ИспользоватьОграничениеПравДоступа = Истина;
    ВызватьИсключение; // Пробрасываем ошибку дальше для анализа
КонецПопытки;

Выясним причину, почему этот способ критикуют. Если пользователь принудительно завершит работу приложения (например, через диспетчер задач) или произойдет критический сбой сервера в момент, когда флаг установлен в Ложь, при определенных настройках системы может возникнуть "дыра" в безопасности. Поэтому использование привилегированных модулей всегда предпочтительнее.

Рекомендации по выбору метода

Проанализируем ситуацию и выберем оптимальный подход:

  1. Если данных немного и отчет не требует интерактивных расшифровок, которые также должны игнорировать RLS — используйте Внешние наборы данных.
  2. Если отчет сложный, с большим объемом данных и множеством настроек — используйте вынос формирования на сервер в привилегированный модуль.
  3. Для современных конфигураций на платформе 8.3 рекомендуется использовать фоновые задания. Фоновое задание может запускаться от имени пользователя, но выполняться в привилегированном режиме на сервере, что изолирует процесс формирования отчета и не блокирует интерфейс.

Таким образом, мы рассмотрели основные технические приемы обхода ограничений RLS в СКД. Главное правило — всегда обеспечивать возврат системы в безопасное состояние и минимизировать время работы кода с повышенными привилегиями.

← На главную