Почему ПривилегированныйРежим() возвращает Ложь после установки в Истина?

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

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

Суть проблемы и типичные симптомы

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


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

Проблема заключается в том, что в одних случаях (например, при вызове из формы списка) режим устанавливается корректно, а в других (при открытии формы документа) — нет. Рассмотрим причины такого «непостоянства».

Причина №1: Влияние безопасного режима расширений

Это самая распространенная причина в современных конфигурациях. Если вы используете расширения конфигурации, обратите внимание на свойство Безопасный режим в настройках расширения. Разберем механизм его работы:

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

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

Решение: Зайдите в меню «Администрирование» — «Печатные формы, отчеты и обработки» — «Расширения» (путь может отличаться в зависимости от конфигурации). Найдите ваше расширение и снимите галочку «Безопасный режим». Также убедитесь, что снята галочка «Защита от опасных действий», если это необходимо для вашей логики.

Причина №2: Клиентский контекст выполнения

Метод УстановитьПривилегированныйРежим работает только на стороне сервера. Посмотрим на типичную ошибку начинающих разработчиков:


&НаКлиенте
Процедура КомандаВыполнить(Команда)
    УстановитьПривилегированныйРежим(Истина); // Ошибки не будет, но и режим не включится
    ВыполнитьДействиеНаСервере();
КонецПроцедуры

Вызов этого метода на клиенте в тонком клиенте не имеет смысла и не переносится на сервер при последующем вызове серверной процедуры. Проанализируем ситуацию: если процедура &НаСервере вызывается из клиентского контекста, привилегированный режим в ней по умолчанию выключен. Его нужно устанавливать внутри серверного метода.

Причина №3: Особенности работы Библиотеки стандартных подсистем (БСП)

Часто проверка прав происходит внутри функций БСП, например, в Пользователи.ЭтоПолноправныйПользователь(). Проанализируем логику этой функции:


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

Если привилегированный режим не «взлетел» из-за настроек безопасности расширения, БСП начнет честную проверку прав пользователя в таблицах базы данных. Если у пользователя нет роли «Полные права» или «Администрирование», функция вернет Ложь, что приведет к ошибке доступа, хотя вы рассчитывали на привилегированный контекст.

Нюансы использования УстановитьПривилегированныйРежим(Ложь)

Важно помнить о правилах «вложенности» режима. Рассмотрим правильный паттерн использования:


Процедура ВыполнитьПоднятиеПрав()
    БылУстановлен = ПривилегированныйРежим();
    УстановитьПривилегированныйРежим(Истина);
    
    // Полезный код...
    
    // Возвращаем режим в исходное состояние только если мы его сами меняли
    Если НЕ БылУстановлен Тогда
        УстановитьПривилегированныйРежим(Ложь);
    КонецЕсли;
КонецПроцедуры

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

Резюме и рекомендации

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

  1. Проверьте расширения: Это наиболее вероятная причина. Отключите «Безопасный режим» для расширения, которое инициирует вызов.
  2. Проверьте контекст: Убедитесь, что вызов происходит в процедуре с директивой &НаСервере или в серверном модуле.
  3. Проанализируйте стек вызовов: Если ошибка плавающая (то есть, то нет), посмотрите через отладчик «Стек вызовов». Если в стеке есть хоть один метод из расширения с включенным безопасным режимом — это причина проблемы.
  4. Проверьте профили безопасности: В клиент-серверном варианте настройки кластера серверов могут принудительно ограничивать использование привилегированного режима для определенных информационных баз через профили безопасности.

Понимание того, как ПривилегированныйРежим взаимодействует с безопасным контекстом расширений, позволит вам избежать труднодиагностируемых ошибок при обновлении и модификации современных конфигураций на базе 1С:Предприятие 8.3.

← На главную