Как проверить права доступа на запись конкретного объекта (строки таблицы) с учетом RLS в 1С?

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

Разработчики в системе «1С:Предприятие» часто сталкиваются с необходимостью программно проверить, имеет ли текущий пользователь право на изменение конкретного элемента справочника, документа или задачи. Ситуация усложняется, когда в базе данных активно используется механизм RLS (Row-Level Security) — ограничение доступа на уровне отдельных записей.

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

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

Опасный обходной путь: попытка записи с откатом транзакции

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


НачатьТранзакцию();
Попытка
    ОбъектДляПроверки = СсылкаНаОбъект.ПолучитьОбъект();
    ОбъектДляПроверки.Записать();
    ОтменитьТранзакцию();
    Возврат Истина; // Права на запись есть
Исключение
    ОтменитьТранзакцию();
    Возврат Ложь; // Права отсутствуют или произошла иная ошибка
КонецПопытки;

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

  1. Необратимые побочные эффекты в обработчиках. При вызове метода Записать() платформа последовательно запускает события ПередЗаписью и ПриЗаписи в модуле объекта, а также все связанные подписки на события. В современных конфигурациях там часто прописана сложная интеграционная логика: отправка HTTP-запросов во внешние базы, отправка SMS или Email-уведомлений, генерация файлов. Отмена транзакции в 1С не способна отменить сетевой запрос, который уже ушел на внешний сервер. В итоге пользователь еще даже не записал объект, а внешняя система уже получила уведомление о его изменении.
  2. Избыточные блокировки СУБД. Попытка записи накладывает эксклюзивные блокировки на таблицы базы данных. Если такую проверку запустить, например, при открытии формы объекта или в динамическом списке для сотен строк, это мгновенно спровоцирует массовые ожидания на блокировках и приведет к падению общей производительности системы.
  3. Пропуски в автонумерации. Для многих документов и бизнес-процессов при начале записи генерируется и резервируется новый номер. При откате транзакции этот зарезервированный номер «сгорает», что приводит к нежелательным пропускам в нумерации документов, вызывая вопросы со стороны бухгалтерии и аудита.

Именно поэтому от тестовой записи объектов необходимо полностью отказаться в пользу штатных механизмов.

Решение проблемы с помощью Библиотеки стандартных подсистем (БСП)

Если ваша конфигурация разработана на основе БСП (а это практически все современные типовые и отраслевые решения: 1С:ERP, 1С:КА, 1С:УТ, 1С:БП, 1С:ЗУП и др.), то в вашем арсенале уже есть готовые, оптимизированные и безопасные функции для проверки ограничений RLS на уровне строк. Все они сосредоточены в общем модуле УправлениеДоступом.

Рассмотрим подробнее три основных метода, разработанных специально для этих целей.

1. Функция УправлениеДоступом.ИзменениеРазрешено()

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

Посмотрим на пример использования:


СсылкаНаЗадачу = ТекущийОбъект.Ссылка;

Если УправлениеДоступом.ИзменениеРазрешено(СсылкаНаЗадачу) Тогда
    // Доступ на редактирование данной строки разрешен.
    // Здесь мы можем открыть форму на редактирование или разрешить интерактивные действия.
Иначе
    // Доступ ограничен настройками RLS.
    // Сообщаем пользователю или блокируем элементы интерфейса.
КонецЕсли;

Метод работает очень быстро и не вызывает никаких транзакционных побочных эффектов, так как не производит физическую запись проверяемого объекта.

2. Процедура УправлениеДоступом.ПроверитьИзменениеРазрешено()

Этот метод аналогичен предыдущему, но вместо возврата Истина или Ложь он сразу вызывает стандартное исключение платформы с понятным для пользователя текстом ошибки, если права отсутствуют. Это избавляет разработчика от необходимости вручную генерировать сообщения об ошибках.

Разберем по шагам логику его применения:


Попытка
    УправлениеДоступом.ПроверитьИзменениеРазрешено(СсылкаНаДокумент);
    // Если код продолжил выполнение, значит, изменение гарантированно разрешено
    ОткрытьФормуДляРедактирования(СсылкаНаДокумент);
Исключение
    // Сюда мы попадем, только если у пользователя действительно нет прав RLS на этот объект.
    // Информация об ошибке уже зафиксирована в описании ошибки.
    ПоказатьПредупреждение(, КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;

3. Оптимизированный метод УправлениеДоступом.ПраваДоступаКДанным()

Что делать, если нам необходимо проверить права на изменение не одного объекта, а целого списка (например, при обработке строк табличной части или выводе кастомного списка)? Вызывать функции ИзменениеРазрешено() в цикле — плохая практика, так как это приведет к множественным одиночным запросам к базе данных.

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

Влияние режима работы RLS на производительность проверок

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

Отладка и расследование проблем RLS через Технологический журнал

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

Для этого в файле настройки технологического журнала logcfg.xml необходимо настроить отслеживание события QERR (Query Error). Это событие фиксирует любые ошибки, связанные с нарушением прав доступа при выполнении запросов СУБД.

Пример настройки секции для сбора логов RLS:


<event filter="QERR">
    <eq property="Name" value="QERR"/>
</event>
<property name="all"/>

В логах события QERR детально отражается исходный текст SQL-запроса с наложенными условиями RLS, параметры запроса и контекст вызова на встроенном языке 1С. Это позволяет быстро локализовать проблемную роль или ограничение доступа, которое привело к отказу в записи объекта.

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

← На главную