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