При администрировании прав пользователей и обновлении конфигураций «1С:Предприятие» разработчики часто сталкиваются с неочевидным поведением системы прав доступа. Типичная ситуация: пользователь выполняет простой запрос к регистру сведений, в тексте запроса нет ни единого прямого упоминания проблемной таблицы, но система выдает ошибку вида: «Недостаточно прав для работы с таблицей "Справочник.ПакетЭДПрисоединенныеФайлы"».
В этой статье мы подробно разберем, почему платформа «1С:Предприятие» обращается к сторонним таблицам базы данных, как оптимизировать такие запросы с помощью оператора ВЫРАЗИТЬ и как бороться со специфическим багом рассинхронизации прав при копировании ролей в Конфигураторе.
Проанализируем классический запрос к регистру сведений ЗначенияСвойствОбъектов, который часто используется в типовых конфигурациях (например, в «Комплексной Автоматизации 1.1» или «Управлении производственным предприятием 1.3»):
ВЫБРАТЬ ПЕРВЫЕ 1
ЗначенияСвойствОбъектов.Объект КАК Объект
ИЗ
РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
ГДЕ
ЗначенияСвойствОбъектов.Свойство = &Свойство
И ЗначенияСвойствОбъектов.Значение = &Значение
И ЗначенияСвойствОбъектов.Объект.ПометкаУдаления = ЛОЖЬ
Обратим внимание на условие в секции ГДЕ: ЗначенияСвойствОбъектов.Объект.ПометкаУдаления = ЛОЖЬ. Измерение Объект имеет составной тип данных. В него могут входить десятки различных справочников и документов системы, включая справочник ПакетЭДПрисоединенныеФайлы, договоры, контрагенты, номенклатуру и другие объекты.
Когда мы обращаемся к реквизиту поля составного типа «через точку» (в данном случае к свойству ПометкаУдаления), платформа «1С:Предприятие» выполняет следующие действия:
ПометкаУдаления, платформа вынуждена построить SQL-запрос с неявным соединением (конструкции LEFT OUTER JOIN) со всеми физическими таблицами объектов, которые теоретически могут быть записаны в поле Объект. Если в составной тип входит 50 справочников, СУБД попытается соединить таблицу регистра со всеми 50 таблицами.РАЗРЕШЕННЫЕ) система безопасности платформы анализирует все таблицы, участвующие в результирующем SQL-запросе. Поскольку неявное соединение вовлекает таблицу Справочник.ПакетЭДПрисоединенныеФайлы, платформа проверяет у текущего пользователя права на чтение этой таблицы. Если у пользователя нет прав на чтение хотя бы одного из объектов, входящих в составной тип измерения Объект, выполнение запроса прерывается ошибкой нарушения прав доступа.Использование ключевого слова РАЗРЕШЕННЫЕ в начале запроса убирает ошибку, заставляя платформу отфильтровать недоступные данные. Однако этот метод не устраняет корневую проблему производительности: СУБД все равно будет тратить ресурсы на избыточные соединения.
Для того чтобы исключить неявные соединения со всеми таблицами составного типа, мы должны жестко указать платформе, к какому типу данных мы обращаемся в конкретный момент запроса. Для этого служит оператор языка запросов ВЫРАЗИТЬ.
Перепишем наш исходный запрос правильно. Предположим, что в данном контексте мы ожидаем получить только характеристики номенклатуры:
ВЫБРАТЬ ПЕРВЫЕ 1
ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Объект КАК Справочник.ХарактеристикиНоменклатуры) КАК Объект
ИЗ
РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
ГДЕ
ЗначенияСвойствОбъектов.Свойство = &Свойство
И ЗначенияСвойствОбъектов.Значение = &Значение
И ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Объект КАК Справочник.ХарактеристикиНоменклатуры).ПометкаУдаления = ЛОЖЬ
Выясним, что изменилось после добавления оператора ВЫРАЗИТЬ:
Объект нужно трактовать исключительно как ссылку на справочник ХарактеристикиНоменклатуры.LEFT JOIN) с таблицей справочника ХарактеристикиНоменклатуры. Все остальные таблицы составного типа (включая проблемный справочник электронных документов) полностью исключаются из обработки.Иногда разработчики сталкиваются с парадоксальной ситуацией: в настройках новой роли (например, созданной копированием роли Пользователь под именем МойПользователь) для проблемного справочника физически стоят галочки «Чтение» и «Просмотр». Однако платформа все равно рапортует о нехватке прав.
Это классический баг кэширования структуры метаданных и прав доступа в Конфигураторе 1С. При копировании тяжелых ролей или обновлении конфигураций поставщика связь между внутренней структурой роли и правами конкретных объектов конфигурации в базе данных может нарушиться. В окне редактирования роли флажки отображаются как активные, но в базу данных конфигурации эти изменения фактически не записались.
Разберем по шагам, как исправить эту рассинхронизацию:
Справочник.ПакетЭДПрисоединенныеФайлы).МойПользователь). Вы увидите, что флажки прав для этой роли здесь могут быть сняты, вопреки тому, что отображалось внутри самого окна редактирования роли!Для глобального решения подобных проблем рекомендуется выполнить операцию Тестирование и исправление базы данных (меню Администрирование — Тестирование и исправление), отметив флажками пункты проверки логической и ссылочной целостности метаданных.
В конфигурациях на платформе «1С:Предприятие 8», разработанных на базе Библиотеки Стандартных Подсистем (БСП) — таких как «Комплексная Автоматизация 1.1», «Управление производственным предприятием 1.3» и других, — роль с системным именем Пользователь является базовой и системной.
Важно: Настоятельно не рекомендуется полностью заменять стандартную роль Пользователь у учетных записей на созданную копию. Программный код многих подсистем (шаблоны ограничений доступа на уровне записей RLS, механизмы работы с файлами, электронная подпись) жестко завязан на проверку системного имени роли через конструкцию РольДоступна("Пользователь").
Если вам необходимо скорректировать права доступа пользователей, лучшей практикой будет:
Пользователь назначенной всем сотрудникам без изменений.ДополнительныеПраваПользователей), в которых определить только измененные или расширенные права доступа.Применяя данные подходы, вы сможете проектировать стабильную, быстродействующую и безопасную систему разграничения прав доступа в конфигурациях 1С.