Как ограничить права доступа к внешнему отчету СКД по ролям

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке внешних отчетов на базе системы компоновки данных (СКД) часто возникает задача ограничить круг лиц, которые могут формировать этот отчет и видеть содержащиеся в нем данные. В отличие от встроенных отчетов конфигурации, где права можно гибко настроить в дереве объектов метаданных, внешние отчеты требуют особого подхода. В этой статье мы подробно разберем, как реализовать проверку прав программно и с помощью встроенных средств СКД.

Способ 1. Простая проверка при попытке формирования (прерывание работы)

Самый быстрый и надежный способ запретить использование отчета — вставить проверку прав в модуль объекта отчета. Для этого мы воспользуемся предопределенной процедурой ПриКомпоновкеРезультата. Эта процедура вызывается системой в тот момент, когда пользователь нажимает кнопку Сформировать.

Рассмотрим простейший пример, когда нам нужно просто прервать выполнение, если у пользователя нет определенной роли. Разберем код:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Проверяем наличие роли "ОсобыеПрава" у текущего пользователя
    Если Не РольДоступна("ОсобыеПрава") Тогда
        // Генерируем исключение, которое остановит процесс формирования
        ВызватьИсключение НСтр("ru = 'Недостаточно прав доступа для формирования данного отчета!'");
    КонецЕсли;

КонецПроцедуры

В данном случае, если проверка РольДоступна возвращает Ложь, система выдаст критическое сообщение об ошибке, и отчет не будет построен. Это жесткий, но эффективный метод "отсечения" неавторизованных пользователей.

Способ 2. Программное формирование с выводом пользовательского сообщения

Если мы хотим, чтобы система вела себя более "дружелюбно", вместо вызова исключения можно вывести информационное сообщение в окно сообщений или непосредственно в табличный документ. Для этого нам потребуется отключить стандартную обработку формирования отчета и описать процесс вывода программно.

Проанализируем ситуацию: когда мы устанавливаем СтандартнаяОбработка = Ложь, мы берем на себя ответственность за инициализацию компоновщика, выполнение макета и вывод результата. Рассмотрим пример кода, который делает это правильно:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Проверяем роль (можно проверять сразу несколько через ИЛИ)
    Если Не (РольДоступна("ОсобыеПрава") Или РольДоступна("ПолныеПрава")) Тогда
        
        СтандартнаяОбработка = Ложь; // Отменяем автоматический вывод
        
        // Сообщаем пользователю о проблеме
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю(НСтр("ru = 'У вас недостаточно прав для просмотра этих данных.'"));
        
        // Очищаем результат, чтобы пользователь не видел старых данных
        ДокументРезультат.Очистить();
        Возврат;
        
    КонецЕсли;
    
    // Если права есть, мы можем либо оставить СтандартнаяОбработка = Истина,
    // либо сформировать отчет вручную для более тонкой настройки.

КонецПроцедуры

Способ 3. Полное программное управление схемой компоновки

Иногда требуется не просто запретить отчет целиком, а выполнить дополнительные действия при наличии прав. В этом случае мы полностью описываем цикл компоновки. Посмотрим на пример кода, который часто применяется в профессиональной разработке:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    СтандартнаяОбработка = Ложь; // Мы сами управляем процессом
    
    Если РольДоступна("РазрешенныйДоступ") Тогда
        
        // 1. Получаем настройки пользователя
        НастройкиОтчета = ЭтотОбъект.КомпоновщикНастроек.ПолучитьНастройки();
        
        // 2. Формируем макет компоновки
        КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
        МакетКомпоновки = КомпоновщикМакета.Выполнить(ЭтотОбъект.СхемаКомпоновкиДанных, НастройкиОтчета, ДанныеРасшифровки);
        
        // 3. Инициализируем процессор компоновки
        ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
        ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
        
        // 4. Выводим результат в табличный документ
        ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
        ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
        ПроцессорВывода.Вывести(ПроцессорКомпоновки);
        
    Иначе
        
        // Если прав нет, просто выводим текст прямо в ячейку отчета
        ДокументРезультат.Очистить();
        Область = ДокументРезультат.Область(1, 1);
        Область.Текст = "Доступ запрещен. Обратитесь к администратору.";
        Область.ЦветТекста = ЦветаСтиля.ЦветОшибкиКритичной;
        
    КонецЕсли;
    
КонецПроцедуры

Способ 4. Использование ограничений на уровне полей СКД

Выясним, как можно ограничить доступ не ко всему отчету, а только к его отдельным частям (например, скрыть колонку "Себестоимость" для менеджеров по продажам). В СКД предусмотрен встроенный механизм управления правами на поля.

Выполним следующие шаги:

  1. Откроем Схему компоновки данных.
  2. Перейдем на закладку Наборы данных.
  3. В списке полей найдем колонку Роли.
  4. Нажав на кнопку выбора в этой колонке, мы можем указать, для каких ролей данное поле доступно.

Важный нюанс: Если у пользователя нет указанной роли, поле просто исчезнет из доступных полей компоновщика. Он не сможет выбрать его в группировках, отборах или выбранных полях. Это наиболее "чистый" способ с точки зрения платформы 1С.

Способ 5. Ограничение через параметры и условия запроса

Рассмотрим ситуацию, когда отчет должен работать для всех, но данные должны фильтроваться в зависимости от прав. Например, руководитель видит все подразделения, а мастер — только свое. Мы можем использовать проверку ролей прямо в выражениях параметров СКД.

Разберем алгоритм настройки:

  1. На закладке Параметры создадим новый параметр, например, &ТолькоСвоиДанные.
  2. В поле Выражение укажем: НЕ РольДоступна("ПолныеПрава").
  3. В тексте запроса набора данных добавим условие:
    
    ГДЕ (НЕ &ТолькоСвоиДанные) ИЛИ (Ответственный = &ТекущийПользователь)
    

Такой подход позволяет избежать использования тяжелого механизма RLS (Row Level Security), который может замедлять работу системы, особенно на больших объемах данных.

Способ 6. Использование БСП (Библиотека стандартных подсистем)

Если вы работаете в современной конфигурации (УТ 11, ERP, БП 3.0), рекомендуется не "хардкодить" роли внутри отчета, а использовать возможности подсистемы "Дополнительные отчеты и обработки".

Проанализируем преимущества этого метода:

Для реализации этого метода достаточно в модуле объекта внешнего отчета правильно описать функцию СведенияОВнешнейОбработке(), указав тип объекта как "Отчет". После регистрации отчета в справочнике, управление доступом переходит на сторону стандартных средств администрирования 1С.

Заключение и рекомендации

Подводя итог, можно выделить три основных уровня защиты внешнего отчета:

  1. Полный запрет: Через процедуру ПриКомпоновкеРезультата в модуле объекта. Это самый надежный способ для защиты конфиденциальных алгоритмов формирования.
  2. Частичный запрет: Через настройки ролей в полях СКД. Идеально подходит для скрытия отдельных финансовых показателей.
  3. Административный запрет: Через механизмы БСП и справочник дополнительных обработок. Это наиболее современный и правильный способ с точки зрения сопровождения системы.

Помните, что проверка прав в коде через РольДоступна() чувствительна к точному написанию имени роли (как оно задано в конфигураторе). Будьте внимательны при переносе отчета между разными базами данных, где набор ролей может отличаться.

← На главную