Почему возникает ошибка доступа RLS, когда документ и связанный объект относятся к разным организациям?

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

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

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

Анализ исходной ситуации и кода

Давайте разберем условия задачи. В конфигурации доработан механизм RLS с добавлением нового разреза доступа — реквизита Регион. Проблема возникает в документе Совмещение. Экспериментально установлено, что ошибка связана с реквизитом СовмещаемаяДолжность, который ссылается на справочник ПозицииШтатногоРасписания.

Ключевое наблюдение, которое привело к решению: документ создан по «Организации №1», а совмещаемая должность относится к «Организации №2». У пользователя есть доступ к обеим организациям, но через две разные группы доступа: одна группа разрешает доступ к «Организации №1», вторая — к «Организации №2».

Посмотрим на шаблоны ограничений, которые были настроены.

Для документа Совмещение шаблон выглядит так:


Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
|	ДляВсехСтрок( ЗначениеРазрешено(ФизическиеЛица.ФизическоеЛицо, NULL КАК ИСТИНА)
|	) И ЗначениеРазрешено(Организация)
|	И ЗначениеРазрешено(Регион, ПустаяСсылка КАК Истина)
|	И ЧтениеОбъектаРазрешено(СовмещающийСотрудник, ПустаяСсылка КАК Истина, NULL как ИСТИНА)
|	И ЧтениеОбъектаРазрешено(ОтсутствующийСотрудник, ПустаяСсылка КАК Истина, NULL как ИСТИНА)
|	И ЧтениеОбъектаРазрешено(СовмещаемаяДолжность, ПустаяСсылка КАК Истина, NULL как ИСТИНА)";

Здесь важно обратить внимание на строку И ЧтениеОбъектаРазрешено(СовмещаемаяДолжность, ...). Эта функция запускает проверку прав на чтение для объекта, на который ссылается реквизит СовмещаемаяДолжность, используя его собственный шаблон RLS.

Для справочника ПозицияШтатногоРасписания шаблон следующий:


Ограничение.Текст =
"ПрисоединитьДополнительныеТаблицы
|ЭтотСписок КАК Т
|ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПодчиненностьПодразделенийОрганизаций КАК Т2 
|	ПО Т2.Подразделение = Т.Подразделение
|;
|РазрешитьЧтение
|ГДЕ
|	ЧтениеОбъектаРазрешено(Т.Владелец, null как Истина)
|	И ЗначениеРазрешено(Т.Регион, ПустаяСсылка КАК Истина)
|;
|РазрешитьИзменениеЕслиРазрешеноЧтение
|ГДЕ
|	ЗначениеРазрешено(Т2.ВышестоящееПодразделение)
|	И ЗначениеРазрешено(Т.Владелец)";

В этом шаблоне доступ к позиции штатного расписания зависит от доступа к ее владельцу (Т.Владелец), которым является организация, и к региону (Т.Регион).

Таким образом, чтобы прочитать документ Совмещение, система должна убедиться, что пользователю разрешены одновременно:

  1. Организация из шапки документа («Организация №1»).
  2. Организация из совмещаемой должности («Организация №2»).

Именно здесь и кроется корень проблемы.

Ключевая особенность: как 1С объединяет права из разных групп доступа

Многие ошибочно полагают, что если у пользователя несколько групп доступа, то система просто собирает все разрешенные значения из всех групп в один большой список по принципу «ИЛИ». Например, если одна группа разрешает «Организацию №1», а вторая — «Организацию №2», то пользователь имеет доступ к обеим. Это верно, но только для простых случаев.

На самом деле механика сложнее. Итоговые права пользователя — это объединение РЕЗУЛЬТАТОВ работы каждой группы, а не объединение списков разрешенных значений.

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

Проанализируем нашу ситуацию по шагам:

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

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

Хорошая аналогия из обсуждения на форуме:

«1 группа доступа: отгрузка разрешена только клиенту Ромашка и только со склада Юг.
2 группа доступа: отгрузка разрешена только клиенту Василёк и только со склада Запад.
Пользователь входит в обе группы доступа. Следует ли из этого, что ему разрешена отгрузка клиенту Ромашка со склада Запад? Очевидно: нет».

Правильное решение: объединение прав в одной группе

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

Пошаговое решение проблемы:

  1. Проанализируйте бизнес-процесс. Определите, какие разрезы доступа (Организации, Подразделения, Регионы и т.д.) могут одновременно участвовать в одной операции. В нашем случае это две разные организации.
  2. Создайте или измените группу доступа. Вместо двух отдельных групп («Доступ к Организации №1» и «Доступ к Организации №2») создайте одну общую, например, «Доступ к филиалам X и Y».
  3. Настройте разрешенные значения. В этой новой группе доступа для вида доступа Организации добавьте в список разрешенных значений обе организации: «Организацию №1» и «Организацию №2».
  4. Назначьте группу пользователю. Включите пользователя в эту новую, объединенную группу доступа. Старые, раздельные группы можно для него отключить, чтобы избежать путаницы.
  5. Обновите права доступа. В производительном режиме RLS после изменения состава групп или шаблонов ограничений необходимо запустить обновление (пересчет) ключей доступа. Обычно это делается через регламентное задание или вручную из раздела администрирования. Автор исходной темы также выполнял очистку регистров КлючиДоступаКОбъектам и ПараметрыДоступа, что является правильной практикой при отладке.

После выполнения этих действий проверка прав будет проходить успешно, так как теперь у пользователя будет одна группа, которая разрешает и «Организацию №1», и «Организацию №2», а значит, вся цепочка проверок в шаблоне RLS отработает корректно.

Общие рекомендации при работе с RLS

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

← На главную