При настройке системы разграничения прав доступа на уровне записей (RLS) в 1С:Предприятии 8 разработчики часто сталкиваются с ситуацией, которая на первый взгляд кажется ошибкой платформы. Суть проблемы заключается в следующем: если на регистр сведений наложено ограничение (например, ГДЕ ЛОЖЬ), но в тексте запроса с использованием ключевого слова РАЗРЕШЕННЫЕ выбираются только измерения, то RLS игнорируется, и пользователь видит все записи. Однако стоит добавить в запрос хотя бы один ресурс или реквизит, как ограничение начинает работать корректно.
В этой статье мы подробно разберем, почему так происходит, как устроена логика платформы 1С и какие шаги нужно предпринять, чтобы обеспечить надежную защиту данных.
Для начала проанализируем, как платформа 1С классифицирует поля объектов при настройке прав доступа. В конфигураторе, когда мы открываем вкладку «Ограничения доступа к данным» для определенной роли, у нас есть возможность выбрать поля, на которые распространяется условие. Часто разработчики выбирают предопределенную группу «Прочие поля».
Важно понимать, что в категорию «Прочие поля» для регистра сведений входят:
Период (для периодических регистров) или НомерСтроки.Измерения регистра сведений в категорию «Прочие поля» не входят. Это ключевой момент. Если вы установили ограничение только на «Прочие поля», то фактически вы сказали системе: «Ограничивай доступ только тогда, когда пользователь пытается прочитать ресурсы или реквизиты». Измерения при этом остаются «открытыми» для платформенных механизмов.
Платформа 1С, начиная с версии 8.3, активно использует механизмы оптимизации при трансляции запросов из языка 1С в SQL. Рассмотрим ситуацию: у нас есть регистр сведений ЦеныНоменклатуры, и мы наложили ограничение ГДЕ ЛОЖЬ на «Прочие поля».
Если мы выполняем следующий запрос:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Т.Номенклатура,
Т.ТипЦен
ИЗ
РегистрСведений.ЦеныНоменклатуры КАК Т
Платформа видит, что в блоке ВЫБРАТЬ используются только поля Номенклатура и ТипЦен. Поскольку это измерения, а на них (согласно настройке роли) ограничение не наложено, оптимизатор 1С решает, что добавлять тяжелое условие RLS к SQL-запросу не нужно. В итоге запрос уходит в СУБД в чистом виде, и пользователь получает список всех комбинаций номенклатуры и типов цен.
Теперь посмотрим, что происходит, когда мы добавляем ресурс Цена:
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Т.Номенклатура,
Т.Цена
ИЗ
РегистрСведений.ЦеныНоменклатуры КАК Т
Здесь платформа фиксирует обращение к полю Цена, которое входит в «Прочие поля» и защищено условием ГДЕ ЛОЖЬ. Чтобы соблюсти права доступа, 1С принудительно модифицирует SQL-запрос, добавляя в него условие, которое отсекает все строки. В результате запрос возвращает пустой результат.
Такое поведение не является «глюком». Оно опирается на философию платформы: измерения идентифицируют запись. Во многих внутренних механизмах (например, при получении структуры ключа записи) платформе необходимо иметь доступ к измерениям, чтобы просто «знать», что запись существует, даже если ее содержание (ресурсы) скрыто.
Однако, если ваша задача — полностью скрыть факт существования записи в регистре, текущая настройка «по полям» вам не подходит.
Существует два основных способа настроить RLS так, чтобы он срабатывал всегда, независимо от состава полей в запросе.
Это самый надежный и рекомендуемый способ, если нужно ограничить доступ к строке целиком.
РегистрСведений.Чтение.ГДЕ Склад = &ПараметрСеанса.ТекущийСклад).При такой настройке ограничение будет применяться к таблице целиком. Даже если программист напишет запрос ВЫБРАТЬ Т.Период ИЗ..., RLS будет активирован, так как ограничение привязано к самому праву на чтение объекта, а не к конкретным колонкам.
Если по каким-то причинам вам нужно разное поведение для разных полей, вы можете явно указать измерения в списке ограничиваемых полей.
Важный нюанс: в 1С права работают по принципу «Разрешено всё, что не запрещено». Если вы ограничили «Прочие поля», но забыли ограничить измерение Организация, то поле Организация будет доступно всем, у кого есть право на чтение объекта.
Чтобы окончательно убедиться в механике работы, мы можем посмотреть на итоговый SQL-запрос. Если RLS настроен только на «Прочие поля», запрос к одним измерениям будет выглядеть примерно так:
SELECT
T1._Fld100, -- Измерение 1
T1._Fld101 -- Измерение 2
FROM
_InfoReg100 T1
Как видим, никаких WHERE или EXISTS с проверкой прав здесь нет. Но как только мы добавим поле, на которое наложен RLS, платформа изменит запрос:
SELECT
T1._Fld100,
T1._Fld102 -- Ресурс
FROM
_InfoReg100 T1
WHERE
1=0 -- Это результат нашего условия "ГДЕ ЛОЖЬ"
Для обеспечения безопасности данных в регистрах сведений при работе с RLS придерживайтесь следующих правил:
ВЫБРАТЬ РАЗРЕШЕННЫЕ во всех запросах, где может сработать RLS, чтобы избежать ошибок нехватки прав, но не полагайтесь на нее как на магический инструмент, исправляющий неверную настройку ролей.Понимание того, как 1С разделяет измерения и ресурсы в правах доступа, позволяет создавать более производительные и защищенные системы. Мы выяснили, что описанное поведение — это сознательная реализация платформы, направленная на оптимизацию доступа к ключевым полям записей.