При доработке механизма ограничения прав доступа (RLS) в 1С, особенно в производительном режиме, можно столкнуться с неочевидными проблемами. Одна из таких ситуаций — возникновение ошибки доступа к документу, когда сам документ относится к одной организации, а связанный с ним объект (например, позиция штатного расписания) — к другой. При этом у пользователя есть права на обе организации, но они предоставлены через разные группы доступа. Разберем, почему так происходит и как это исправить.
Проанализируем конкретный случай: в конфигурации 1С:ЗУП был доработан RLS, но при открытии документа «Совмещение» пользователь получает ошибку «Ошибка доступа. Чтение», хотя по отдельности может открывать и сам документ, и все связанные с ним объекты.
Давайте разберем условия задачи. В конфигурации доработан механизм RLS с добавлением нового разреза доступа — реквизита Регион. Проблема возникает в документе Совмещение. Экспериментально установлено, что ошибка связана с реквизитом СовмещаемаяДолжность, который ссылается на справочник ПозицииШтатногоРасписания.
Ключевое наблюдение, которое привело к решению: документ создан по «Организации №1», а совмещаемая должность относится к «Организации №2». У пользователя есть доступ к обеим организациям, но через две разные группы доступа: одна группа разрешает доступ к «Организации №1», вторая — к «Организации №2».
Посмотрим на шаблоны ограничений, которые были настроены.
Для документа Совмещение шаблон выглядит так:
Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
| ДляВсехСтрок( ЗначениеРазрешено(ФизическиеЛица.ФизическоеЛицо, NULL КАК ИСТИНА)
| ) И ЗначениеРазрешено(Организация)
| И ЗначениеРазрешено(Регион, ПустаяСсылка КАК Истина)
| И ЧтениеОбъектаРазрешено(СовмещающийСотрудник, ПустаяСсылка КАК Истина, NULL как ИСТИНА)
| И ЧтениеОбъектаРазрешено(ОтсутствующийСотрудник, ПустаяСсылка КАК Истина, NULL как ИСТИНА)
| И ЧтениеОбъектаРазрешено(СовмещаемаяДолжность, ПустаяСсылка КАК Истина, NULL как ИСТИНА)";
Здесь важно обратить внимание на строку И ЧтениеОбъектаРазрешено(СовмещаемаяДолжность, ...). Эта функция запускает проверку прав на чтение для объекта, на который ссылается реквизит СовмещаемаяДолжность, используя его собственный шаблон RLS.
Для справочника ПозицияШтатногоРасписания шаблон следующий:
Ограничение.Текст =
"ПрисоединитьДополнительныеТаблицы
|ЭтотСписок КАК Т
|ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПодчиненностьПодразделенийОрганизаций КАК Т2
| ПО Т2.Подразделение = Т.Подразделение
|;
|РазрешитьЧтение
|ГДЕ
| ЧтениеОбъектаРазрешено(Т.Владелец, null как Истина)
| И ЗначениеРазрешено(Т.Регион, ПустаяСсылка КАК Истина)
|;
|РазрешитьИзменениеЕслиРазрешеноЧтение
|ГДЕ
| ЗначениеРазрешено(Т2.ВышестоящееПодразделение)
| И ЗначениеРазрешено(Т.Владелец)";
В этом шаблоне доступ к позиции штатного расписания зависит от доступа к ее владельцу (Т.Владелец), которым является организация, и к региону (Т.Регион).
Таким образом, чтобы прочитать документ Совмещение, система должна убедиться, что пользователю разрешены одновременно:
Именно здесь и кроется корень проблемы.
Многие ошибочно полагают, что если у пользователя несколько групп доступа, то система просто собирает все разрешенные значения из всех групп в один большой список по принципу «ИЛИ». Например, если одна группа разрешает «Организацию №1», а вторая — «Организацию №2», то пользователь имеет доступ к обеим. Это верно, но только для простых случаев.
На самом деле механика сложнее. Итоговые права пользователя — это объединение РЕЗУЛЬТАТОВ работы каждой группы, а не объединение списков разрешенных значений.
Это означает, что для получения доступа к объекту (в нашем случае, к документу Совмещение) должна найтись хотя бы одна группа доступа, которая разрешает этот объект целиком, со всеми его связанными проверками.
Проанализируем нашу ситуацию по шагам:
ЗначениеРазрешено(Организация) для документа проходит успешно, так как организация документа — «Организация №1».ЧтениеОбъектаРазрешено(СовмещаемаяДолжность). Она пытается проверить доступ к позиции, которая принадлежит «Организации №2».ЗначениеРазрешено(Организация) для документа проваливается, так как организация документа («Организация №1») не разрешена в этой группе.Поскольку ни одна из групп доступа не смогла полностью разрешить чтение документа, пользователь получает ошибку доступа. Система не может «взять» разрешение на организацию документа из одной группы, а разрешение на организацию должности — из другой, и объединить их.
Хорошая аналогия из обсуждения на форуме:
«1 группа доступа: отгрузка разрешена только клиенту Ромашка и только со склада Юг.
2 группа доступа: отгрузка разрешена только клиенту Василёк и только со склада Запад.
Пользователь входит в обе группы доступа. Следует ли из этого, что ему разрешена отгрузка клиенту Ромашка со склада Запад? Очевидно: нет».
Исходя из логики работы механизма RLS, решение становится очевидным: необходимо так настроить группы доступа, чтобы все необходимые для операции права находились в рамках одной группы.
Пошаговое решение проблемы:
Организации добавьте в список разрешенных значений обе организации: «Организацию №1» и «Организацию №2».КлючиДоступаКОбъектам и ПараметрыДоступа, что является правильной практикой при отладке.После выполнения этих действий проверка прав будет проходить успешно, так как теперь у пользователя будет одна группа, которая разрешает и «Организацию №1», и «Организацию №2», а значит, вся цепочка проверок в шаблоне RLS отработает корректно.
ЗначениеРазрешено — быстрая проверка значения по заранее рассчитанным спискам. ЧтениеОбъектаРазрешено — более медленная, но надежная проверка, которая запускает полный механизм RLS для связанного объекта. Используйте ее, когда доступ к текущим данным зависит от прав на связанные.Таким образом, успешная работа с RLS требует не только правильного написания шаблонов ограничений, но и глубокого понимания того, как система обрабатывает права, полученные из нескольких групп доступа.