Ограничение доступа на уровне записей: устройство, синтаксис, отладка
Содержание
RLS в 1С (Record Level Security, ограничение доступа на уровне записей) настраивается в Конфигураторе: откройте роль, выберите объект, отметьте право «Чтение» или «Изменение» и впишите условие в поле «Ограничение доступа к данным» внизу окна. Условие пишется на языке запросов, а платформа добавляет его к каждому запросу, который обращается к этой таблице.
Чаще всего RLS нужен, когда пользователь должен видеть документы только своей организации, своего склада или своего подразделения. Ниже — как механизм устроен изнутри, как написать условие без потерь в скорости и что делать, когда после включения ограничений у пользователей посыпались ошибки.
Как устроен механизм RLS: от роли до SQL-запроса
RLS — это не функция СУБД. Ни MS SQL, ни PostgreSQL про ваши роли ничего не знают. Всё делает платформа 1С: перед тем как отправить запрос в базу, она встраивает в него условие из роли текущего пользователя.
Цепочка выглядит так:
- Пользователь открывает список документов, отчёт или выполняет код с запросом.
- Платформа определяет его роли и находит для нужной таблицы и нужного права текст ограничения.
- Текст ограничения превращается в дополнительные условия и подзапросы.
- В СУБД уходит уже расширенный SQL-запрос. Лишние строки отсекаются на стороне базы.
Отсюда три практических следствия:
- 🔒 Ограничение работает одинаково в файловом и клиент-серверном варианте. В файловой базе роль СУБД играет сама платформа, логика та же.
- 🐢 Каждое условие RLS — это нагрузка на каждый запрос к таблице. Тяжёлое условие замедляет всё: списки, отчёты, проведение.
- 🧩 Если у пользователя несколько ролей, условия объединяются через «ИЛИ». Запись доступна, если её разрешает хотя бы одна роль.
Роль без ограничения на объект даёт полный доступ к нему, даже если в другой роли того же пользователя стоит строгое условие. Это самая частая причина «RLS не работает ».
Какие права можно ограничить
Ограничение задаётся отдельно для каждого права:
| Право | Когда проверяется условие |
|---|---|
| Чтение | При любом запросе и чтении объекта |
| Добавление | При записи нового объекта |
| Изменение | При записи: условие должно выполняться и до, и после изменения |
| Удаление | При удалении объекта |
Для права «Изменение» проверка двойная. Если пользователь с доступом только к «ООО Альфа» откроет документ «Альфы» и поменяет организацию на «Бету», запись будет отклонена.
Где задаётся условие и как его записать
Путь в Конфигураторе: Конфигурация → Общие → Роли → двойной щелчок по роли → объект в дереве → право в правой части → поле «Ограничение доступа к данным» внизу окна.
У поля две колонки: «Поля» и «Ограничение». Если поля не указаны, условие действует на всю запись. Если указаны — только когда запрос читает перечисленные поля. Это позволяет, например, скрыть суммы в документе, но оставить видимыми номер и дату.
Простая форма условия
В простой форме пишется только то, что стоит после ГДЕ. Поля текущей таблицы указываются без псевдонима:
Организация = &ТекущаяОрганизация
Здесь &ТекущаяОрганизация — параметр сеанса. В RLS можно использовать только параметры сеанса, обычные параметры запроса недоступны.
Условие может содержать подзапрос. Пример: пользователь видит документы по складам, которые ему разрешены в отдельном регистре сведений:
Склад В (
ВЫБРАТЬ
Доступ.Склад
ИЗ
РегистрСведений.ДоступКСкладам КАК Доступ
ГДЕ
Доступ.Пользователь = &ТекущийПользователь)
Параметры сеанса
Параметры сеанса создаются в ветке Общие → Параметры сеанса и заполняются в модуле сеанса:
Процедура УстановкаПараметровСеанса(ИменаПараметров)
Если ИменаПараметров = Неопределено Тогда
ТекущийПользователь = Справочники.Пользователи.НайтиПоНаименованию(
ПользователиИнформационнойБазы.ТекущийПользователь().Имя);
ПараметрыСеанса.ТекущийПользователь = ТекущийПользователь;
КонецЕсли;
КонецПроцедуры
Пример упрощённый: в типовых конфигурациях пользователь ищется по идентификатору пользователя ИБ, а не по имени. Тип параметра может быть фиксированным массивом. Тогда условие пишется как Организация В (&РазрешенныеОрганизации), и подзапрос к регистру при каждом обращении не нужен.
Значения параметров сеанса живут, пока жив сеанс. Если вы поменяли права пользователя в регистре, а параметр заполняется массивом при входе, пользователь увидит изменения только после перезапуска 1С.
Шаблоны ограничений
Когда одно и то же условие нужно повесить на 40 документов, копировать текст неудобно. Для этого на форме роли есть закладка «Шаблоны ограничений». Шаблон вызывается через решётку:
#ПоОрганизации("Организация")
Внутри шаблона параметры подставляются конструкцией #Параметр(1), а имя текущей таблицы — #ТекущаяТаблица. Есть и инструкции препроцессора #Если … #Тогда … #КонецЕсли: они позволяют строить разный текст условия в зависимости от параметров шаблона. Именно так устроены ограничения в типовых конфигурациях на базе БСП.
Пример настройки: документы только своей организации
Разберём рабочий сценарий с нуля в собственной конфигурации. Задача: менеджер видит и меняет только документы «Реализация товаров» своих организаций.
- Создайте регистр сведений
ДоступКОрганизациямс измерениямиПользовательиОрганизация. - Создайте параметр сеанса
РазрешенныеОрганизациис типомФиксированныйМассив. - В модуле сеанса заполните его запросом к регистру по текущему пользователю и оберните результат в
Новый ФиксированныйМассив(...). - Откройте роль «Менеджер», найдите документ, выберите право «Чтение» и впишите условие
Организация В (&РазрешенныеОрганизации). - Повторите для прав «Добавление» и «Изменение».
- Сохраните конфигурацию, обновите конфигурацию базы данных и войдите под тестовым пользователем с этой ролью.
Заполнение параметра в модуле сеанса:
Запрос = Новый Запрос(
"ВЫБРАТЬ
| Д.Организация
|ИЗ
| РегистрСведений.ДоступКОрганизациям КАК Д
|ГДЕ
| Д.Пользователь = &Пользователь");
Запрос.УстановитьПараметр("Пользователь", ПараметрыСеанса.ТекущийПользователь);
Массив = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Организация");
ПараметрыСеанса.РазрешенныеОрганизации = Новый ФиксированныйМассив(Массив);
Модуль сеанса выполняется в привилегированном режиме, поэтому запрос к регистру доступа отработает, даже если у самой роли на регистр прав нет. В остальном коде так не получится.
RLS в запросах и отчётах на СКД
Как только на таблице появилось ограничение чтения, все запросы к ней в коде нужно проверить. Запрос без слова РАЗРЕШЕННЫЕ при попадании на запрещённую запись падает с ошибкой прав. С ним — просто не возвращает лишние строки:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Р.Ссылка,
Р.СуммаДокумента
ИЗ
Документ.РеализацияТоваровУслуг КАК Р
В отчётах на системе компоновки данных (СКД) правило то же: в запросе набора данных пишите ВЫБРАТЬ РАЗРЕШЕННЫЕ. Иначе отчёт у пользователя с ограничениями будет падать, а у администратора — работать, и ошибку долго не могут поймать.
Настройка RLS в типовых конфигурациях
В типовых решениях условия в ролях уже написаны разработчиками. Администратору нужно только включить механизм и раздать доступ.
В 1С:Бухгалтерии 3.0 путь такой: Администрирование → Настройки пользователей и прав → флажок «Ограничивать доступ на уровне записей». Затем в группах доступа указываются организации, к которым у группы есть доступ. В Бухгалтерии ограничение строится по организациям.
В конфигурациях на БСП 3.x используется так называемое универсальное ограничение. Разработчик описывает его не в роли, а в модуле менеджера объекта:
Процедура ПриЗаполненииОграничения(Ограничение) Экспорт
Ограничение.Текст =
"РазрешитьЧтениеИзменение
|ГДЕ
| ЗначениеРазрешено(Организация)";
КонецПроцедуры
БСП сама рассчитывает ключи доступа и хранит их в служебных регистрах. В роли остаётся короткий шаблон, который сводит проверку к соединению по ключу. Это быстрее, чем подзапрос к правам при каждом обращении.
После первого включения ограничения в большой базе БСП обновляет ключи доступа фоновым заданием. Пока оно не закончится, часть данных пользователи могут не видеть. Включайте механизм вечером, а не в понедельник утром.
Как RLS влияет на скорость и что с этим делать
Ограничение срабатывает при каждом обращении к таблице: в списке, отчёте, при проведении. Поэтому условие пишут так же внимательно, как запрос в самом нагруженном отчёте.
Что ускоряет:
- ⚡ Сравнение с параметром сеанса (
Организация В (&РазрешенныеОрганизации)) вместо подзапроса. - 📇 Индексирование полей, по которым идёт отбор. Измерения регистров индексируются автоматически, у реквизитов документов включайте свойство «Индексировать».
- 🔑 Ключи доступа (подход БСП): одно соединение по ключу вместо цепочки условий.
Что замедляет:
- 🐌 Обращение через точку:
Договор.Контрагент.ОсновнойМенеджер = &Пользователь. Каждая точка — дополнительное соединение таблиц в SQL. - 🐌 Условия с
ИЛИпо разным полям: СУБД хуже использует индексы. - 🐌 Ограничения на измерения регистров с большим числом записей без подходящего индекса.
Сравнение подходов:
| Подход | Скорость | Когда подходит | Риски |
|---|---|---|---|
| Параметр сеанса с массивом | Высокая | Десятки значений, редкая смена прав | Изменения видны после перезахода |
| Подзапрос к регистру прав | Средняя | Права меняются часто | Тормозит на больших таблицах |
| Разыменование через точку | Низкая | Почти никогда | Соединения в каждом запросе |
| Ключи доступа БСП | Высокая | Типовые конфигурации, сложные права | Долгий первичный расчёт ключей |
Если сомневаетесь, во что превращается ваш запрос, посмотрите текст SQL в профилировщике СУБД или в технологическом журнале. Подзапросы из RLS там хорошо видны.
Различия между веб-клиентом, тонким и толстым клиентом
Само ограничение от типа клиента не зависит. Условие применяется там, где выполняется запрос, а это всегда серверная часть платформы. Различается другое — где можно выполнить код и обойти ограничение.
- 🌐 Веб-клиент и тонкий клиент. Запросы выполняются только на сервере. Код на клиенте вызывает серверные процедуры, и RLS применяется к ним без исключений.
- 🖥️ Толстый клиент (обычное приложение). Запросы можно выполнять прямо в клиентском коде, в файловом варианте всё работает внутри одного процесса. Ограничения при этом тоже действуют: данные всё равно читает платформа.
- 🔓 Привилегированный режим.
УстановитьПривилегированныйРежим(Истина)и общие модули с флажком «Привилегированный» отключают проверку прав. В тонком и веб-клиенте это доступно только в серверном коде.
Привилегированный режим нужен для служебных задач: проведения документа, которое пишет движения в регистры без прав у пользователя, или расчёта итогов. Но любой серверный метод в привилегированном режиме, который возвращает данные на клиент, — дыра в RLS. Проверяйте, что именно такая процедура отдаёт наружу.
Как поведение видит пользователь
В списках и отчётах с РАЗРЕШЕННЫЕ запрещённые записи просто не показываются. Ошибку пользователь получает, когда код читает конкретный объект без прав: открывает ссылку из чужого документа, проводит документ, который ссылается на запрещённую запись, или запускает отчёт с запросом без РАЗРЕШЕННЫЕ. Типичный текст — Нарушение прав доступа! с указанием операции и таблицы.
Частые ошибки при настройке и как их найти
Чтобы быстро проверить, какие роли что разрешают, в Конфигураторе в контекстном меню ветки «Роли» есть команда «Все роли». Она показывает сводную таблицу прав по объектам. Финальную проверку всегда делайте под тестовым пользователем с тем же набором ролей, что у реального сотрудника, а не под администратором.
Правки ролей требуют обновления конфигурации базы данных. В рабочей базе делайте это вне рабочего времени и после резервной копии: на время обновления пользователей нужно вывести из базы.