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