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