Как проанализировать права доступа RLS к конкретным объектам в БСП

Программист IT и автоматизация бизнеса
← На главную

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

Понимание архитектуры ключей доступа БСП

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

Система группирует объекты с одинаковыми настройками доступа в один ключ, а пользователей с одинаковыми правами — в другой. Связь между ними определяет, разрешен ли доступ. Основные данные хранятся в следующих регистрах:

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

Способ 1: Использование прямых запросов к регистрам (Самый быстрый)

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

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


ВЫБРАТЬ РАЗЛИЧНЫЕ
    КлючиПользователей.Пользователь КАК Пользователь
ИЗ
    РегистрСведений.КлючиДоступаКОбъектам КАК КлючиОбъектов
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КлючиДоступаПользователей КАК КлючиПользователей
        ПО КлючиОбъектов.КлючДоступа = КлючиПользователей.КлючДоступа
ГДЕ
    КлючиОбъектов.Объект = &КонтрагентСсылка

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

Теперь рассмотрим обратную задачу: какие контрагенты доступны конкретному пользователю? Для этого модифицируем наш запрос:


ВЫБРАТЬ
    КлючиОбъектов.Объект КАК ДоступныйКонтрагент
ИЗ
    РегистрСведений.КлючиДоступаПользователей КАК КлючиПользователей
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.КлючиДоступаКОбъектам КАК КлючиОбъектов
        ПО КлючиПользователей.КлючДоступа = КлючиОбъектов.КлючДоступа
ГДЕ
    КлючиПользователей.Пользователь = &ТекущийПользователь
    И КлючиОбъектов.ТипМетаданных = &ТипКонтрагенты

Важный момент: данный метод работает только в том случае, если в информационной базе включен "Производительный режим" работы RLS. Проверить это можно в разделе Администрирование — Настройки пользователей и прав.

Способ 2: Программная проверка через API БСП

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

Выясним, как проверить доступ к конкретному объекту для другого пользователя, не меняя текущий сеанс. Проанализируем пример кода:


// Проверка права "Чтение" для конкретного пользователя и объекта
ДоступРазрешен = УправлениеДоступом.ЕстьПраво("Чтение", ОбъектСсылка, НужныйПользователь);

Если ДоступРазрешен Тогда
    Сообщить("Пользователь имеет доступ к объекту");
КонецЕсли;

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

Способ 3: Имитация сеанса пользователя (Регламентные задания)

Иногда возникают ситуации, когда права настроены крайне сложно (например, с использованием параметров сеанса, зависящих от времени или внешних данных), и обычный анализ ключей доступа может быть неточным. В таких случаях можно прибегнуть к методу "запуска под пользователем".

Рассмотрим пошагово, как это реализовать:

  1. Создадим вспомогательный регистр сведений или временную таблицу для хранения результатов.
  2. Напишем процедуру, которая выполняет запрос ВЫБРАТЬ РАЗРЕШЕННЫЕ из таблицы контрагентов.
  3. Запустим эту процедуру через ФоновыеЗадания.Выполнить(), передав в параметрах структуру с ключом ИмяПользователя.

Пример программного запуска фонового задания под другим пользователем:


ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(НужныйПользователь);

ФоновыеЗадания.Выполнить("МойОбщийМодуль.СформироватьСписокДоступныхОбъектов", 
                         ПараметрыЗадания, 
                         "АнализДоступа_" + НужныйПользователь.Наименование);

Этот метод гарантирует 100% точность, так как 1С применит реальные механизмы RLS текущего сеанса пользователя. Однако помните о нагрузке на сервер: не стоит запускать десятки таких заданий одновременно.

Использование инструментов разработчика БСП

Проанализируем еще один вариант, который часто забывают программисты. В составе дистрибутива БСП поставляется внешняя обработка "Инструменты разработчика: Управление доступом". Она позволяет визуально исследовать:

Если вам нужно разово выяснить причину отсутствия доступа, эта обработка — лучший инструмент. Она наглядно показывает всю цепочку: от роли и профиля до конкретного ключа доступа в регистре.

Резюме и рекомендации

Выясним, какой метод выбрать в зависимости от ситуации:

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

← На главную