Как в БСП настроить раздельный RLS на чтение и изменение по подразделениям?

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

В типовых конфигурациях и при доработке систем на базе «Библиотеки стандартных подсистем» (БСП) часто возникает задача гибкого разграничения доступа к документам. Типичный сценарий: пользователям требуется видеть документы по одной группе подразделений (или вообще по всем), но редактировать разрешено только документы строго определенных подразделений.

Рассмотрим, с какими сложностями платформы и подсистемы «Управление доступом» можно столкнуться при реализации такого правила, а также подробно разберем все рабочие варианты решения задачи.

В чем заключается сложность реализации в БСП

Попытка решить задачу «в лоб» часто вызывает трудности по следующим причинам:

  1. Ограничение на одинаковый тип значений у разных видов доступа: По умолчанию БСП проектируется по правилу «один тип данных — один вид доступа». Если создать вид доступа «Подразделения (чтение)» и «Подразделения (запись)» со ссылкой на СправочникСсылка.Подразделения, подсистема выдаст исключение, если не отключен признак ВидДоступаЕдинственныйДляТипаЗначенияДоступа.
  2. Связка ролей и профилей: БСП агрегирует права через служебный регистр сведений ТаблицыГруппДоступа. Флаг Изменение в этом регистре выставляется только для тех групп доступа, чьи роли предоставляют право на изменение таблицы. При неправильной комбинации ролей шаблон RLS на запись не находит сопоставленных разрешений и блокирует доступ.

Вариант 1. Разделение через две роли и два профиля групп доступа

Разберем классический подход с использованием типовых возможностей БСП. Он заключается в разделении ответственности на уровне ролей:

  1. Создаем Роль 1 (Только чтение): В ней на документ даются права Чтение и Просмотр. Для права Чтение прописывается стандартный шаблон RLS #ПоЗначениям по виду доступа Подразделение. Права на изменение и добавление отсутствуют.
  2. Создаем Роль 2 (Изменение): В ней даются права Изменение, Добавление (и обычно Чтение). На каждое право назначается шаблон #ПоЗначениям по тому же виду доступа Подразделение.
  3. Настраиваем профили: В пользовательском режиме создаем Профиль 1 (только Роль 1) и Профиль 2 (только Роль 2).
  4. Назначаем группы доступа: Пользователю назначаются две группы. В первой задается широкий список подразделений для чтения, а во второй — узкий список подразделений, доступных для редактирования.

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

Вариант 2. Использование механизма наборов значений доступа

Если требуется хранить точные флаги прав для каждого документа индивидуально, наиболее мощным штатным средством БСП выступает механизм наборов значений доступа (шаблон #ПоНаборамЗначений).

Рассмотрим, как устроен этот механизм:

  1. Документ включается в определяемый тип ВладелецНаборовЗначенийДоступа.
  2. В модуле объекта документа переопределяется стандартная процедура формирования наборов:

Процедура ЗаполнитьНаборыЗначенийДоступа(ТаблицаНаборов) Экспорт
    
    // Добавляем строку для подразделения документа
    СтрокаНабора = ТаблицаНаборов.Добавить();
    СтрокаНабора.НомерНабора = 1;
    СтрокаНабора.ВидДоступа  = ПланВидовХарактеристик.УдалитьВидыДоступа.Подразделения;
    СтрокаНабора.ЗначениеДоступа = Подразделение;
    
    // Флаг чтения доступен для просмотра
    СтрокаНабора.Чтение = Истина;
    
    // Флаг изменения выставляется по бизнес-логике
    Если ЭтоРазрешенноеПодразделениеДляПравки(Подразделение) Тогда
        СтрокаНабора.Изменение = Истина;
    Иначе
        СтрокаНабора.Изменение = Ложь;
    КонецЕсли;

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

В ограничениях прав роли вместо простого шаблона используется #ПоНаборамЗначений, что позволяет полностью развязать логику видимости документа и возможности его интерактивной корректировки.

Вариант 3. RLS на чтение + программный контроль на изменение (Рекомендуемый)

Проанализируем производительность системы. Использование RLS на операцию Изменение создает существенную нагрузку на сервер СУБД в момент записи объекта и при проведении, провоцируя взаимоблокировки транзакций при одновременной работе пользователей.

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

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

  1. Оставляем RLS по шаблону #ПоЗначениям только для права Чтение (или даем полное чтение без RLS, если документы должны видеть все).
  2. На стороне формы блокируем интерфейс от случайных правок. В модуле формы документа в процедуре ПриСозданииНаСервере или ПослеЗаписиНаСервере устанавливаем доступность:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Не ПравоНаРедактированиеПодразделения(Объект.Подразделение) Тогда
        ЭтаФорма.ТолькоПросмотр = Истина;
    КонецЕсли;

КонецПроцедуры
  1. Для гарантированной защиты на уровне базы данных обязательно дублируем контроль в обработчике события перед записью самого объекта (или в общей подписке на событие):

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

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

Такой подход обеспечивает высокую производительность СУБД, исключает скрытые блокировки транзакций и позволяет прозрачно управлять правами без усложнения структуры шаблонов RLS.

← На главную