Как ограничить доступ к документам «Заявка на расходование денежных средств» по группам пользователей в 1С:УПП?

Программист 1С v8.3 (Обычные формы) Управленческий учет Финансы и профессиональные услуги
← На главную

В крупных и средних компаниях часто возникает задача разграничения прав доступа к финансовым документам. Типичный сценарий: руководство требует, чтобы сотрудники одного отдела (например, отдела продаж) не видели документы «Заявка на расходование денежных средств», созданные сотрудниками другого отдела (например, бухгалтерии или ИТ). Это необходимо для соблюдения конфиденциальности, в частности, для сокрытия информации о бюджетах на заработную плату, премиях или иных чувствительных расходах.

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

Анализ проблемы и постановка задачи

Каждый пользователь информационной базы должен видеть только те заявки на расходование средств, которые созданы сотрудниками из его «группы» (отдела). В метаданных документа ДокументСсылка.ЗаявкаНаРасходованиеЧерныхСредств (или в типовом ЗаявкаНаРасходованиеДенежных Средств) присутствует реквизит Ответственный, который ссылается на справочник СправочникСсылка.Пользователи.

Нам необходимо настроить механизм RLS (Record Level Security — ограничение доступа на уровне записей) для роли пользователя таким образом, чтобы система сравнивала группу текущего авторизованного пользователя и группу пользователя, указанного в реквизите Ответственный документа.

Разбор решения с использованием иерархии справочника «Пользователи»

На форумах часто предлагают быстрое решение: сгруппировать пользователей по папкам в справочнике Пользователи (например, создать папки «Отдел продаж», «Бухгалтерия») и написать RLS-запрос, который проверяет родителя текущего пользователя.

В самом простом виде этот запрос выглядит следующим образом:


ГДЕ Ответственный.Родитель В (ВЫБРАТЬ Родитель ИЗ Справочник.Пользователи ГДЕ Ссылка = &ТекущийПользователь)

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

Критические недостатки данного подхода:

  1. Проблема жесткой иерархии: Справочник Пользователи может содержать многоуровневую структуру. Если внутри папки отдела появится хотя бы одна подпапка (например, в папке «Бухгалтерия» появится подпапка «Расчетчики»), то вышеуказанный запрос перестанет работать для пользователей из этой подпапки, так как их непосредственный Родитель уже не совпадет с родителем коллег уровнем выше.
  2. Проблема производительности при использовании иерархии: Чтобы обойти проблему многоуровневой структуры, разработчики часто прибегают к использованию оператора В ИЕРАРХИИ. Запрос принимает следующий вид:
    
    ГДЕ Ответственный В ИЕРАРХИИ (ВЫБРАТЬ Родитель ИЗ Справочник.Пользователи ГДЕ Ссылка = &ТекущийПользователь)
    
    Использование В ИЕРАРХИИ в шаблонах ограничений RLS приводит к тому, что СУБД (например, MS SQL Server) генерирует крайне сложные рекурсивные запросы. На таблицах документов с сотнями тысяч записей это вызовет колоссальные задержки при открытии динамических списков, зависание интерфейса и частые взаимоблокировки базы данных (Lock Escalation).
  3. Архитектурное ограничение: Элемент справочника в 1С может принадлежать только одному родителю. Это означает, что один пользователь физически не может находиться в двух разных группах. Если в вашей компании руководитель должен видеть заявки как отдела продаж, так и отдела логистики, данная схема полностью потеряет свою работоспособность.

Решение #1: Настройка RLS через стандартный справочник «Группы пользователей»

Для обхода ограничений иерархии справочника пользователей в 1С существует стандартный справочник ГруппыПользователей. Один пользователь может одновременно состоять в неограниченном количестве групп. Это дает необходимую гибкость.

Рассмотрим, как написать оптимальный с точки зрения производительности RLS-запрос для ограничения чтения документов по группам пользователей. Наша задача — разрешить чтение документа только в том случае, если автор (Ответственный) состоит хотя бы в одной общей группе с текущим пользователем.

Разберем по шагам создание шаблона RLS для права «Чтение» у документа ЗаявкаНаРасходованиеДенежныхСредств:

  1. Откройте конфигуратор, найдите нужную роль (или создайте новую, например, ОграничениеДоступаЗаявкиПоГруппам).
  2. Перейдите на вкладку «Права», выберите документ ЗаявкаНаРасходованиеДенежныхСредств.
  3. Для права «Чтение» в окне ограничений доступа добавьте новое поле и вставьте следующий оптимизированный запрос:

ГДЕ Ответственный В 
    (ВЫБРАТЬ ТабСостав.Пользователь 
     ИЗ Справочник.ГруппыПользователей.Пользователи КАК ТабСостав
     ГДЕ ТабСостав.Ссылка В 
         (ВЫБРАТЬ ТабГруппы.Ссылка 
          ИЗ Справочник.ГруппыПользователей.Пользователи КАК ТабГруппы 
          ГДЕ ТабГруппы.Пользователь = &ТекущийПользователь))

Почему этот запрос работает быстро?

В отличие от тяжелых иерархических запросов с В ИЕРАРХИИ, этот запрос работает по плоским табличным частям Пользователи справочника ГруппыПользователей. СУБД легко оптимизирует подобные запросы с использованием индексов, что исключает появление «зависаний» при открытии журналов документов.

Решение #2: Использование типового механизма УПП (без программирования)

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

У документа Заявка на расходование денежных средств есть обязательный реквизит Подразделение (или ПодразделениеОрганизации). В большинстве организаций структура групп пользователей полностью совпадает со структурой подразделений компании.

Выясним, как настроить ограничение доступа по подразделениям без доработки конфигурации:

  1. Перейдите в режим «1С:Предприятие» под правами администратора.
  2. Откройте настройки параметров учета и убедитесь, что включена константа «Использовать ограничения прав доступа на уровне записей».
  3. Перейдите в меню Сервис -> Пользователи -> Настройка прав доступа.
  4. Выберите нужную группу пользователей (или создайте новую, например, «Отдел сбыта»).
  5. В таблице «Виды объектов доступа» выберите Подразделения.
  6. В подчиненной таблице настроек укажите перечень подразделений, документы которых разрешено видеть и изменять участникам этой группы.

При такой настройке платформа автоматически будет фильтровать документы «Заявка на расходование денежных средств» по реквизиту Подразделение. Пользователи увидят только те документы, подразделение которых входит в список их разрешенных объектов доступа. Это наиболее надежный метод, не требующий снятия конфигурации с поддержки.

Важные подводные камни при внедрении RLS

Если вы приняли решение использовать программное ограничение через RLS (Решение #1), обязательно учитывайте следующие важные архитектурные особенности платформы «1С:Предприятие»:

1. Принцип объединения прав (логическое ИЛИ)

Если у пользователя в профиле есть хотя бы одна роль, дающая доступ к чтению документа ЗаявкаНаРасходованиеДенежныхСредств БЕЗ ограничений (например, типовая роль Бухгалтер или МенеджерПоПродажам), то ваш кастомный RLS-запрос работать не будет! Платформа суммирует права по принципу «Разрешено все, что разрешено хотя бы одной ролью». Чтобы ограничение сработало, вам необходимо внедрить разработанный RLS-запрос во все роли пользователя, дающие право чтения этого документа, либо забрать у пользователя лишние роли.

2. Обязательное индексирование полей

Поле, по которому происходит фильтрация в RLS (в нашем случае реквизит Ответственный), должно быть обязательно проиндексировано. Откройте свойства документа в конфигураторе, найдите реквизит Ответственный и убедитесь, что свойство Индексировать установлено в значение Индексировать или Индексировать с доп. упорядочиванием. Если этого не сделать, при росте базы данных производительность системы резко снизится.

3. Влияние на проведение и запись документов

Ограничение RLS влияет не только на интерактивное отображение документов в списках, но и на работу программного кода. Если при проведении другого связанного документа (например, ПлатежноеПоручениеИсходящее) система попытается программно прочитать данные ограниченной заявки, у пользователя возникнет ошибка «Недостаточно прав для работы с базой данных». Обязательно протестируйте всю цепочку документооборота под тестовым пользователем с ограниченными правами перед запуском системы в промышленную эксплуатацию.

← На главную