Как исправить ошибку «Отказ в доступе» к регистру «Версии объектов» при программной записи документа из внешней обработки?

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

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

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

---

Выясняем причину: почему интерактивно документ записывается, а программно — нет?

Для начала проанализируем, что происходит в системе в обоих случаях. Когда в конфигурации включено версионирование объектов, при любой записи документа (будь то создание нового или изменение существующего) система пытается зафиксировать его текущее состояние в служебном регистре сведений РегистрСведений.ВерсииОбъектов.

Обычные пользователи не имеют прямого доступа на изменение этого регистра — право на запись есть только у роли ПолныеПрава. Как же тогда документ успешно записывается интерактивно?

Дело в том, что в типовых конфигурациях запись в регистр версий выполняется внутри общего модуля БСП, код которого выполняется в привилегированном режиме. Когда пользователь нажимает кнопку «Записать» на форме документа:

  1. Запускается стандартная транзакция записи документа.
  2. Срабатывает подписка на событие перед записью или при записи.
  3. Код БСП вызывает переход в привилегированный режим с помощью метода УстановитьПривилегированныйРежим(Истина).
  4. Система временно игнорирует ограничения прав текущего пользователя и успешно выполняет запись в регистр ВерсииОбъектов.
  5. Транзакция завершается, привилегированный режим отключается.

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

---

Главный виновник — безопасный режим исполнения кода

Когда внешняя обработка или отчет подключаются к системе через справочник «Дополнительные отчеты и обработки», платформа по умолчанию запускает их в так называемом безопасном режиме (параметр БезопасныйРежим = Истина).

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

В безопасном режиме полностью блокируется возможность перехода в привилегированный режим!

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

Рассмотрим код внешней обработки, который вызывает эту ошибку:


&НаСервере
Процедура СоздатьДокументНаСервере()
    
    // Создаем документ программно
    Док = Документы.ТребованиеНакладная.СоздатьДокумент();
    Док.Дата = ТекущаяДата();
    
    // Заполнение обязательных реквизитов...
    
    // Здесь произойдет аварийное завершение с ошибкой доступа
    Док.Записать(РежимЗаписиДокумента.Запись); 
    
КонецПроцедуры

---

Способ 1. Отключение безопасного режима (Решение автора)

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

Посмотрим на пример функции СведенияОВнешнейОбработке с отключенным безопасным режимом:


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

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

Минусы этого решения: это небезопасно. В крупных компаниях системные администраторы и специалисты по безопасности блокируют установку внешних обработок с параметром БезопасныйРежим = Ложь. Более того, такая обработка гарантированно не пройдет аудит для публикации в облачном сервисе (например, в «1С:Fresh»).

---

Способ 2. Использование точечных разрешений БСП (Рекомендуемый и безопасный способ)

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

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


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

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

---

Способ 3. Перенос логики в расширение конфигурации

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

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

Резюме

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

← На главную