В практике разработчика 1С часто возникает ситуация, когда необходимо выполнить запрос или действие в обход ограничений прав доступа (RLS) или при отсутствии у пользователя прав на конкретные объекты метаданных. Стандартным инструментом для этого является метод УстановитьПривилегированныйРежим(Истина). Однако при попытке вызвать его внутри внешней обработки многие сталкиваются с тем, что под правами администратора код отрабатывает успешно, а под обычным пользователем — игнорируется, и система выдает ошибку доступа. Рассмотрим подробно, почему это происходит и как правильно решить данную задачу.
Проанализируем ситуацию, описанную в исходном вопросе. Разработчик пытается выполнить следующий код на сервере в модуле формы внешней обработки:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ * ИЗ Справочник.Контрагенты"; // Пример запроса
УстановитьПривилегированныйРежим(Истина);
Выборка = Запрос.Выполнить().Выбрать();
УстановитьПривилегированныйРежим(Ложь);
Основная причина, по которой этот код не работает для рядового пользователя, заключается в том, что внешние отчеты и обработки, открываемые через меню «Файл — Открыть», автоматически запускаются в безопасном режиме, если у пользователя нет административных прав (ролей «Администратор системы» или «Полные права»).
Разберем, что именно блокирует безопасный режим. Когда платформа устанавливает для программного кода БезопасныйРежим = Истина, вступают в силу следующие ограничения:
УстановитьПривилегированныйРежим(Истина) просто не выполняется, при этом система не выдает никакой ошибки, она молча продолжает работу в контексте текущих прав пользователя.Выполнить() и Вычислить().Это сделано для обеспечения безопасности системы: чтобы «внешний» код, который не прошел проверку разработчиком конфигурации, не мог получить несанкционированный доступ к конфиденциальным данным или нанести вред операционной системе.
Иногда разработчики пытаются программно отключить безопасный режим прямо из кода обработки, используя метод УстановитьБезопасныйРежим(Ложь). Однако это не даст результата. Если обработка уже запущена платформой в безопасном режиме, она не может сама себе «повысить» уровень доверия. Это было бы логической дырой в системе безопасности 1С. Попытка вызвать УстановитьБезопасныйРежим(Ложь) внутри кода, который уже находится под защитой, будет просто проигнорирована.
Проанализируем наиболее правильный и современный способ решения проблемы. Если ваша конфигурация построена на базе Библиотеки стандартных подсистем (БСП), не следует открывать обработку через «Файл — Открыть». Вместо этого её нужно зарегистрировать в справочнике Дополнительные отчеты и обработки.
Рассмотрим по шагам, как это работает:
УстановитьПривилегированныйРежим(Истина), и он успешно сработает даже у пользователя с ограниченными правами.Важно помнить, что за безопасность в данном случае отвечает администратор, который осознанно разрешил данной конкретной обработке работать без ограничений.
Если по каким-то причинам использование БСП невозможно или неудобно, существует архитектурный способ решения проблемы. Мы можем создать в основной конфигурации специальный «мостик».
Разберем этот метод подробнее:
Сервер и Привилегированный.Привилегированный означает, что весь код внутри этого модуля всегда выполняется с полными правами, игнорируя RLS. При этом нам даже не нужно писать внутри него УстановитьПривилегированныйРежим(Истина).Пример кода в общем модуле РаботаСДаннымиПривилегированная:
Функция ПолучитьДанныеКонтрагентов(ТекстЗапроса) Экспорт
Запрос = Новый Запрос(ТекстЗапроса);
Возврат Запрос.Выполнить().Выгрузить();
КонецФункции
Теперь из внешней обработки мы просто вызываем этот модуль:
// Код во внешней обработке
Результат = РаботаСДаннымиПривилегированная.ПолучитьДанныеКонтрагентов("ВЫБРАТЬ ТОП 10 Ссылка ИЗ Справочник.Контрагенты");
Этот метод считается безопасным, так как администратор конфигурации сам определяет, какие именно «окна» в данных он открывает для внешних вызовов. Внешняя обработка, даже находясь в безопасном режиме, имеет право вызывать экспортные методы общих модулей конфигурации.
Если вы запускаете внешнюю обработку программно из кода другой обработки или модуля, вы можете управлять безопасным режимом через менеджер внешних обработок. Рассмотрим пример:
// Программное подключение на сервере
ПутьКФайлу = "C:\ExternalProc.epf";
ИмяОбработки = ВнешниеОбработки.Подключить(ПутьКФайлу, , Ложь); // Третий параметр - БезопасныйРежим
ОбработкаОбъект = ВнешниеОбработки.Создать(ИмяОбработки);
ОбработкаОбъект.ВыполнитьНужноеДействие();
Обратите внимание на третий параметр метода Подключить. Если передать туда Ложь, обработка будет подключена в обычном (небезопасном) режиме. Однако для выполнения самого метода ВнешниеОбработки.Подключить() с выключенным безопасным режимом у текущего пользователя должны быть соответствующие административные права.
Важно помнить еще об одном нюансе, который часто упускают новички. Метод УстановитьПривилегированныйРежим() работает только на сервере.
Если вы напишете этот код в процедуре модуля формы с директивой &НаКлиенте, платформа не выдаст ошибку, но режим включен не будет. Всегда проверяйте, где именно исполняется ваш код. Для проверки того, активен ли режим в данный момент, используйте встроенную функцию ПривилегированныйРежим(), которая возвращает Истина или Ложь.
Рассмотрим пример отладочного кода:
&НаСервере
Процедура ВыполнитьНаСервере()
УстановитьПривилегированныйРежим(Истина);
Если ПривилегированныйРежим() Тогда
Сообщить("Режим успешно включен");
Иначе
Сообщить("Не удалось включить привилегированный режим - проверьте настройки безопасности!");
КонецЕсли;
// ... ваш код ...
УстановитьПривилегированныйРежим(Ложь);
КонецПроцедуры
Если УстановитьПривилегированныйРежим(Истина) не работает во внешней обработке под обычным пользователем, это нормальное поведение платформы 1С:Предприятие 8.3, защищающее базу от несанкционированного доступа.
Для решения проблемы мы рекомендуем:
Понимание механизмов безопасного режима позволяет создавать не только функциональные, но и защищенные решения на платформе 1С.