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