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