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