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