Почему при RLS по полям объектная модель возвращает пустые значения и как это правильно исправить?

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

Настройка ограничений доступа на уровне записей (RLS) — одна из наиболее сложных и ответственных задач при проектировании прав доступа в системе «1С:Предприятие». Часто разработчики сталкиваются с ситуацией, когда казалось бы правильно настроенные права на отдельные поля ведут себя непредсказуемо во встроенном языке. Классический пример: мы разрешили чтение полей Ссылка и Наименование, но закрыли доступ к остальным («прочим») полям. При попытке прочитать наименование через точку от ссылки в коде мы неожиданно получаем пустую строку.

В этой статье мы подробно проанализируем, почему так происходит, разберем внутренние механизмы платформы 1С и СУБД, а также научимся правильно обходить это ограничение с помощью запросов.

Суть схемы «Прочие поля — ГДЕ ЛОЖЬ»

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

Если мы полностью закроем объект для чтения пользователю, то во всех связанных объектах, отчетах и динамических списках он увидит крайне неинформативную надпись <Объект не найден...> (так называемые «битые ссылки»). Чтобы избежать этого визуального дефекта, применяется следующий прием настройки прав на чтение объекта:

  1. Для полей Ссылка, Наименование и Код (или Дата и Номер для документов) ограничение RLS оставляется пустым или настраивается как ГДЕ ИСТИНА. Это значит, что базовая информация об объекте всегда доступна для чтения.
  2. Для категории <Прочие поля> (куда входят все остальные реквизиты, табличные части и свойства) устанавливается ограничение ГДЕ ЛОЖЬ. Это наглухо закрывает доступ к детальной информации.

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

Выясняем причину: почему ломается объектная модель?

Рассмотрим ситуацию, когда разработчик пытается получить разрешенное поле (например, Наименование) через обращение к ссылке во встроенном языке:


// Попытка получить наименование элемента через объектную модель
ИмяЭлемента = СсылкаНаОбъект.Наименование;
КомментарийЭлемента = СсылкаНаОбъект.Комментарий;

В отладчике мы увидим странную картину: и Наименование, и Комментарий, и все прочие реквизиты будут абсолютно пустыми, хотя на Наименование у нас есть явное право просмотра, а сам элемент физически существует в базе данных. Ошибки нарушения прав при этом не возникает.

Давайте разберем по шагам, что происходит в этот момент под капотом платформы:

  1. Любое обращение через точку к реквизиту ссылки (например, СсылкаНаОбъект.Наименование) или вызов метода ПолучитьОбъект() инициирует обращение к объектному кэшу платформы 1С.
  2. Если данных в кэше нет, платформа выполняет к СУБД SQL-запрос на получение всех полей данной таблицы для текущей записи. Платформа 1С «не умеет» читать объект по частям через объектную модель. Ей обязательно нужно прочитать и закэшировать всю запись целиком.
  3. СУБД перехватывает этот запрос и накладывает на него правила RLS. Поскольку для части полей (для категории <Прочие поля>) действует жесткое ограничение ГДЕ ЛОЖЬ, СУБД возвращает платформе отказ в доступе на чтение всей записи, так как в выборку попали запрещенные колонки.
  4. Платформа 1С трактует этот отказ не как фатальную ошибку (ведь на саму ссылку права есть), а как невозможность заполнить объектный кэш. В результате объект инициализируется значениями по умолчанию — пустой строкой, нулевыми датами и неопределенными ссылками.

Важное правило: объектный метод работы с данными в 1С всегда требует полного доступа ко всей записи. Если хотя бы одно поле закрыто через RLS, объектный кэш не будет построен, и все реквизиты вернутся пустыми.

Решение проблемы: переход на запросы

Единственным правильным решением для обхода этой особенности является использование явных запросов к базе данных. В отличие от объектной модели, механизм запросов позволяет гибко управлять составом выбираемых полей.

Проанализируем пример правильного кода для получения разрешенных данных:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ РАЗРЕШЕННЫЕ
    |	Номенклатура.Ссылка КАК Ссылка,
    |	Номенклатура.Наименование КАК Наименование
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	Номенклатура.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", СсылкаНаОбъект);

Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
    // Здесь мы гарантированно получим корректное заполненное наименование
    ИмяЭлемента = Выборка.Наименование;
Иначе
    ИмяЭлемента = "";
КонецЕсли;

Почему этот подход работает успешно?

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

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

Для каждого проверяемого поля платформа вынуждена генерировать сложные вложенные подзапросы с многочисленными соединениями (LEFT JOIN). В высоконагруженных базах данных со многими тысячами записей это неизбежно приводит к сильному замедлению работы отчетов и динамических списков.

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

Если специфика вашего проекта все же требует использования классического RLS с разделением полей, всегда помните о золотом правиле разработчика 1С: любое чтение данных в условиях активного RLS должно выполняться исключительно через запросы с явным перечислением полей и ключевым словом РАЗРЕШЕННЫЕ. Это убережет ваши алгоритмы от получения пустых значений и обеспечит стабильную работу системы.

← На главную