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