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