Почему не работает УстановитьПривилегированныйРежим во внешней обработке 1С?

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

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

Проанализируем типовой пример кода, в котором возникает ошибка:


УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗЛИЧНЫЕ
    |	СоответствиеРозничныхСкладовПоОрганизации.Склад,
    |	СоответствиеРозничныхСкладовПоОрганизации.Организация
    |ИЗ
    |	РегистрСведений.СоответствиеРозничныхСкладовПоОрганизации КАК СоответствиеРозничныхСкладовПоОрганизации";

ТаблицаОрганизаций = Запрос.Выполнить().Выгрузить();

При выполнении этого кода у пользователя без полных прав возникает ошибка: «Недостаточно прав на чтение данного регистра». Разберем по шагам, почему платформа игнорирует включение привилегированного режима и какими способами можно решить эту проблему.

Причина поведения платформы: действие безопасного режима

Основная причина кроется в том, что код исполняется в контексте внешней обработки или внешнего отчета. При интерактивном открытии файла обработки через главное меню (Файл - Открыть) платформа 1С автоматически запускает её в безопасном режиме.

В безопасном режиме действуют следующие ограничения:

  1. Вызов метода УстановитьПривилегированныйРежим(Истина) не вызывает синтаксической или рантайм-ошибки, однако платформа фактически игнорирует команду и не отключает проверку прав доступа и RLS.
  2. Запрещено выполнение потенциально опасных действий (работа с COM-объектами, запуск внешних приложений, загрузка внешних компонент и доступ к файловой системе сервера).

Проверим фактическое состояние привилегированного режима с помощью функции ПривилегированныйРежим():


УстановитьПривилегированныйРежим(Истина);
Если ПривилегированныйРежим() Тогда
    // В безопасном режиме внешней обработки управление сюда не попадет
    ВыполнитьДействие();
Иначе
    // Функция вернет Ложь, так как безопасный режим блокирует переключение
    ВызватьИсключение "Не удалось включить привилегированный режим!";
КонецЕсли;

Способ 1. Вынос логики в привилегированный общий модуль конфигурации

Самый надежный и архитектурно правильный способ обойти ограничение — вынести код чтения данных в общий модуль конфигурации или расширения.

Разберем порядок действий:

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

Пример кода функции в привилегированном общем модуле:


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

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

Способ 2. Программное подключение внешней обработки с отключением безопасного режима

Если внешняя обработка открывается или создается программно, разработчик может явно передать параметр отключения безопасного режима.

Посмотрим на примеры программного открытия:


// Создание объекта внешней обработки из файла на диске
ОбработкаОбъект = ВнешниеОбработки.Создать(ПутьКФайлу, Ложь);

// Подключение обработки из двоичных данных/хранилища значений
ИмяОбработки = ВнешниеОбработки.Подключить(АдресВоВременномХранилище, , Ложь);

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

Важное ограничение: Отключить безопасный режим программно может только пользователь, обладающий административными правами (роль с правом Администрирование).

Способ 3. Использование подсистемы «Дополнительные отчеты и обработки» (БСП)

Если конфигурация разработана на базе Библиотеки стандартных подсистем (БСП), внешнюю обработку рекомендуется встроить в справочник ДополнительныеОтчетыИОбработки.

В модуле объекта внешней обработки в экспортной функции СведенияОВнешнейОбработке() необходимо явно указать параметры безопасного режима:


Функция СведенияОВнешнейОбработке() Экспорт

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

КонецФункции

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

Способ 4. Перенос функционала в расширение конфигурации

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

В свойствах расширения доступно отключение признака Безопасный режим, а также создание собственных привилегированных серверных общих модулей, что снимает все ограничения на доступ к закрытым для роли данным.

← На главную