Как исправить ошибку «Действие недоступно в безопасном режиме» при записи внешней обработки в 1С:Фреш?

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

Разработка внешних отчетов и обработок для сервиса 1С:Фреш (1cFresh) имеет свою специфику, связанную с жесткими требованиями безопасности. Одной из частых проблем, с которой сталкиваются разработчики после обновления библиотек (БСП) в облаке, является невозможность программной записи объекта обработки. Ошибка звучит как «Действие недоступно в безопасном режиме».

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

Суть проблемы и причины возникновения

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


// Пример кода, вызывающего ошибку
ОбработкаОбъект = СсылкаНаЭтуОбработкуВБазе.ПолучитьОбъект();
ОбработкаОбъект.ХранилищеНастроек = Новый ХранилищеЗначения(НастройкиОбработки);
ОбработкаОбъект.Записать(); // Здесь возникает исключение

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

Дело в том, что в последних версиях БСП (особенно в ветках 3.1.9 и старше) усилен контроль за изменением справочников, входящих в состав подсистемы «Дополнительные отчеты и обработки». Чтобы лучше ориентироваться в доступных программных интерфейсах, рекомендуем использовать справочник по методам БСП (с примерами использования). Когда вы вызываете метод Записать(), срабатывает подписка на событие или процедура ПриЗаписи в модуле объекта справочника. Внутри этой процедуры система пытается выполнить действия, требующие высоких привилегий.

Поскольку внешняя обработка в 1С:Фреш всегда выполняется в Безопасном режиме (Safe Mode), любые попытки выполнить привилегированные действия блокируются платформой. В локальной базе это может работать, если вы запускаете 1С под полными правами без профиля безопасности, но в облаке правила строже.

Решение 1: Использование Привилегированного режима (Legacy метод)

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

Давайте пройдем этот путь по шагам.

Шаг 1. Запрос разрешения в манифесте

В функции СведенияОВнешнейОбработке, которая формирует структуру регистрации для сервиса, необходимо добавить запрос разрешения. Просто так включить привилегированный режим в безопасной среде нельзя — это нужно задекларировать.

Рассмотрим, как это делается:


Функция СведенияОВнешнейОбработке() Экспорт
    
    ПараметрыРегистрации = Новый Структура;
    // ... заполнение стандартных параметров ...
    
    // Формируем массив разрешений
    Разрешения = Новый Массив;
    
    // Добавляем разрешение на использование привилегированного режима
    Разрешения.Добавить(
        РаботаВБезопасномРежиме.РазрешениеНаИспользованиеПривилегированногоРежима(
            "Для сохранения настроек обработки требуется запись объекта"
        )
    );
    
    ПараметрыРегистрации.Вставить("Разрешения", Разрешения);
    
    Возврат ПараметрыРегистрации;
    
КонецФункции

Шаг 2. Реализация в коде и прохождение аудита

Здесь кроется главный нюанс, о который спотыкаются многие разработчики. Казалось бы, мы запросили разрешение, значит, код должен заработать. Но робот-аудитор сервиса 1С:Фреш, а также любой современный статический анализатор кода проектов, работают по принципу: «Если разрешение запрошено, оно должно быть явно использовано».

Если вы просто добавите разрешение, но оставите код записи ОбработкаОбъект.Записать() как есть, вы можете получить отказ при аудите с формулировкой: «В обработке запрошено разрешение на использование Привилегированного режима, но не используется».

Чтобы удовлетворить и технические требования платформы, и требования аудита, необходимо обернуть вызов записи в блок установки привилегированного режима.


// Правильная реализация записи
ОбработкаОбъект = СсылкаНаЭтуОбработкуВБазе.ПолучитьОбъект();
ОбработкаОбъект.ХранилищеНастроек = Новый ХранилищеЗначения(НастройкиОбработки);

// Явно устанавливаем привилегированный режим
УстановитьПривилегированныйРежим(Истина);
Попытка
    ОбработкаОбъект.Записать();
Исключение
    // Обработка ошибки
    УстановитьПривилегированныйРежим(Ложь);
    ВызватьИсключение;
КонецПопытки;
// Отключаем режим (хотя он отключится автоматически при выходе из процедуры, лучше явно)
УстановитьПривилегированныйРежим(Ложь);

Важно: Такой подход позволяет «пробить» ограничения безопасного режима для конкретной операции записи и одновременно показывает аудитору, что запрашиваемое разрешение действительно необходимо в коде.

Решение 2: Использование Хранилища общих настроек (Рекомендуемое)

Давайте посмотрим на проблему шире. Изменение объекта справочника (сама обработка хранится в справочнике ДополнительныеОтчетыИОбработки) только ради сохранения пользовательских настроек — это не самая лучшая практика, особенно в высоконагруженных облачных системах.

Более современным и безопасным способом является использование стандартного механизма платформы — ХранилищеОбщихНастроек. Также в некоторых случаях может быть полезна специализированная подсистема предопределенных настроек. Этот метод работает даже в безопасном режиме и не требует получения объекта и его перезаписи.

Рассмотрим, как переписать код сохранения настроек:


// Сохранение настроек
КлючОбъекта = "НастройкиМоейОбработки";
КлючНастроек = "ОсновныеНастройки"; 
// Или можно привязаться к пользователю
ИмяПользователя = ПользователиИнформационнойБазы.ТекущийПользователь().Имя;

// Сохраняем структуру настроек
ХранилищеОбщихНастроек.Сохранить(
    КлючОбъекта, 
    КлючНастроек, 
    НастройкиОбработки, 
    , 
    ИмяПользователя
);

И соответственно, чтение настроек при открытии:


// Чтение настроек
НастройкиОбработки = ХранилищеОбщихНастроек.Загрузить(
    КлючОбъекта, 
    КлючНастроек, 
    , 
    ИмяПользователя
);

Если НастройкиОбработки = Неопределено Тогда
    // Инициализируем настройки по умолчанию
КонецЕсли;

Этот способ предпочтительнее, так как он не вызывает конфликтов с системой безопасности БСП и проходит аудит без лишних вопросов.

Дополнительные нюансы: Версии БСП

В процессе обсуждения проблемы часто упоминается манипуляция с версией БСП в параметрах регистрации. Некоторые разработчики пытаются указать старую версию (например, 2.1.0.0), чтобы заставить систему работать по старым алгоритмам.


ПараметрыРегистрации.Вставить("ВерсияБСП", "2.1.0.0"); // Не рекомендуется

Мы настоятельно не рекомендуем использовать этот метод. Техническая поддержка сервиса 1С:Фреш может отклонить такую обработку, так как указание заведомо ложной версии БСП нарушает стандарты и методики разработки конфигураций 1С. Кроме того, это может привести к тому, что параметры запуска обработки перестанут корректно передаваться, если внутренняя логика облачной подсистемы изменится.

Другие виды разрешений

Если ваша обработка выполняет иные действия, которые блокируются безопасным режимом, принцип остается тем же: нужно запросить конкретное разрешение через объект РаботаВБезопасномРежиме.

Например, если вы используете временные файлы для обмена данными или формирования отчетов в фоне, вам понадобится разрешение на использование каталога временных файлов:


Разрешения.Добавить(
    РаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаВременныхФайлов(
        Истина, // Чтение
        Истина, // Запись
        "Для работы с временными файлами при формировании отчета"
    )
);

Резюме

  1. Ошибка «Действие недоступно в безопасном режиме» при записи объекта вызвана проверками прав в модулях БСП при записи справочника дополнительных отчетов.
  2. Для сохранения подхода с записью объекта необходимо добавить разрешение РазрешениеНаИспользованиеПривилегированногоРежима в манифест и обязательно обернуть вызов .Записать() в УстановитьПривилегированныйРежим(Истина).
  3. Наиболее правильным и безопасным решением является отказ от записи объекта в пользу использования ХранилищеОбщихНастроек.
← На главную