При настройке прав доступа и ограничений на уровне записей (RLS) в «1С:Предприятии 8» разработчики часто сталкиваются с неявным поведением платформы. Типичная ситуация: вы настроили ограничение доступа для справочника Номенклатура, затем решили его удалить или изменить, но у пользователя всё равно возникает критическая ошибка:
Ошибка при вызове метода контекста (Выполнить) по причине: У пользователя недостаточно прав на исполнение операции над базой данных.
Особенно удивляет тот факт, что ошибка может воспроизводиться избирательно — например, только при открытии элементов из конкретной папки (например, «Изделия»), тогда как другие элементы справочника открываются и редактируются без каких-либо проблем. В этой статье мы подробно разберем, почему возникает эта ошибка, как связаны механизмы Критериев отбора и RLS, и как решить проблему по шагам.
Проанализируем архитектуру платформы «1С:Предприятие». В типовых конфигурациях при открытии формы элемента номенклатуры (или при записи) часто срабатывает код, проверяющий связанные ссылки. Обычно это делается с помощью запроса к критерию отбора, например: КритерийОтбора.СсылкиНаНоменклатуру.
Рассмотрим, как работает этот механизм под капотом:
UNION ALL таблицы всех объектов (документов, справочников, регистров), которые входят в состав этого критерия в конфигураторе.РАЗРЕШЕННЫЕ, платформа обязана проверить наличие у пользователя прав на чтение абсолютно всех таблиц, входящих в состав этого критерия.РАЗРЕШЕННЫЕ мгновенно вызовет исключение безопасности. Платформа аварийно завершит работу с ошибкой «У пользователя недостаточно прав».Именно поэтому удаление RLS непосредственно со справочника Номенклатура не решает проблему. Запрос спотыкается на проверке прав связанных документов!
Это самый частый повод для недоумения. Если дело в правах на документы, почему другие папки номенклатуры открываются успешно?
Здесь в силу вступают особенности оптимизации запросов СУБД и специфика данных:
Если у вас есть доступ к изменению кода конфигурации (напрямую или через механизм расширений), это самый правильный и безопасный путь. Нам необходимо принудительно заставить платформу игнорировать записи таблиц, к которым у текущего пользователя нет доступа.
Посмотрим на пример стандартного запроса, вызывающего ошибку:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылки.Ссылка КАК Ссылка
|ИЗ
| КритерийОтбора.СсылкиНаНоменклатуру(&Ссылка) КАК Ссылки";
Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);
Результат = Запрос.Выполнить();
Для исправления ситуации мы должны добавить директиву ограничения выборки разрешенными записями:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| Ссылки.Ссылка КАК Ссылка
|ИЗ
| КритерийОтбора.СсылкиНаНоменклатуру(&Ссылка) КАК Ссылки";
Запрос.УстановитьПараметр("Ссылка", Объект.Ссылка);
Результат = Запрос.Выполнить();
В этом случае платформа просто отфильтрует из результата те документы, на которые у пользователя нет прав, и запрос выполнится корректно без генерации исключения.
Если запрос выполняется в модуле объекта, модуле менеджера или в общем модуле, вызов кода можно обернуть в привилегированный режим. Привилегированный режим полностью отключает проверку RLS на время выполнения операции, что не только решит проблему с правами, но и значительно ускорит выполнение запроса.
Применим этот подход на практике:
УстановитьПривилегированныйРежим(Истина);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылки.Ссылка КАК Ссылка
|ИЗ
| КритерийОтбора.СсылкиНаНоменклатуру(&Ссылка) КАК Ссылки";
Запрос.УстановитьПараметр("Ссылка", ПолучитьСсылкуНоменклатуры());
Результат = Запрос.Выполнить();
УстановитьПривилегированныйРежим(Ложь);
Важное правило: Старайтесь всегда отключать привилегированный режим сразу после того, как критичный к правам участок кода был выполнен, чтобы не создавать уязвимостей в безопасности системы.
Если ваша конфигурация разработана на базе Библиотеки стандартных подсистем (БСП) (например, ERP, КА, УТ или крупные отраслевые решения), в ней, скорее всего, используется производительный режим работы RLS. При этом режиме права рассчитываются не динамически "на лету", а кэшируются в специальных регистрах сведений (таких как КлючиДоступаКОбъектам, КлючиДоступаКРегистрам и др.).
Когда вы вручную меняете RLS или роли в Конфигураторе, этот кэш становится неактуальным, и система продолжает выдавать ошибку прав, ориентируясь на устаревшие данные в регистрах.
Для исправления рассинхронизации выполним следующие шаги:
ИнструментыРазработчикаОбновлениеВспомогательныхДанных.epf (ее можно найти в дистрибутиве БСП вашей версии).1cv8.exe ENTERPRISE /F "ПутьКБазе" /C ЗапуститьОбновлениеИнформационнойБазы.При динамическом обновлении конфигурации в клиент-серверном варианте работы серверные процессы rphost часто кэшируют старые схемы запросов и настройки ограничений RLS.
Обычная очистка локального кэша с ключом /ClearCache здесь не поможет, так как она сбрасывает только клиентские метаданные и формы. Требуется очистить кэш на стороне сервера приложений:
sh /etc/init.d/srv1cv83 restart на Linux или через консоль «Службы» в Windows).rphost), на которых запущены сеансы проблемных пользователей. При этом сеансы автоматически пересоздадутся на новых процессах с чистым кэшем прав.