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