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