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