Как настроить ограничение доступа RLS на уровне отдельных полей справочника в 1С:Предприятие?

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

При проектировании прав доступа часто возникает задача предоставить пользователю возможность видеть общую информацию обо всех элементах справочника (например, наименование, ИНН, КПП), но скрыть конфиденциальные реквизиты (контакты, условия работы, персональные скидки), если текущий пользователь не является ответственным менеджером. Попытка решить эту задачу с помощью стандартного механизма RLS (Record Level Security) на уровне отдельных полей роли часто приводит к ошибкам платформы: зависаниям при записи, надписям «<Объект не найден...>» и сообщениям о нарушении прав доступа. Разберем по шагам, как устроен данный механизм, почему возникают ошибки и какие архитектурные решения позволяют корректно реализовать требуемое поведение.

Особенности работы RLS на уровне полей и причины ошибок

Проанализируем, как платформа 1С:Предприятие обрабатывает ограничения доступа на уровне отдельных реквизитов объекта метаданных:

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

Настройка роли с ограничением по полям в конфигураторе

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

1. Для общедоступных полей (Ссылка, Наименование, ИНН, КПП) зададим полное условие чтения:

ГДЕ ИСТИНА

2. Для поля Прочие поля зададим ограничение по значению реквизита Менеджер и параметру сеанса ТекущийПользователь:


ГДЕ Менеджер В (&ТекущийПользователь, ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка))

В этом случае в динамических списках чужие элементы будут корректно отображать наименование и реквизиты идентификации, а значения закрытых полей будут возвращаться как NULL. Однако открыть стандартную форму элемента или записать такой объект пользователь не сможет.

Рекомендуемые архитектурные альтернативы

Рассмотрим проверенные способы решения задачи, которые сохраняют стабильность типовых механизмов платформы и не блокируют работу пользователей.

Вариант 1. Разделение данных по отдельным объектам метаданных

Это наиболее надежный архитектурный подход. Разделим данные на общедоступные и конфиденциальные:

  1. В основном справочнике Контрагенты оставляем общедоступные данные (Наименование, ИНН, КПП, Ссылка) и предоставляем на справочник полные права на чтение без RLS. Это обеспечивает бесперебойную работу механизмов выбора в документах, проведения и формирования связей.
  2. Конфиденциальные данные (контакты, банковские счета, коммерческие условия) выносим в подчиненный справочник или независимый регистр сведений, где измерением выступает Контрагент, а реквизитом — Менеджер.
  3. На подчиненный объект метаданных накладываем стандартный построчный RLS (или типовой механизм БСП по значениям доступа). Чужие менеджеры просто не увидят конфиденциальные записи, при этом основная функциональность конфигурации не нарушится.

Вариант 2. Программное ограничение видимости на уровне интерфейса

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

1. В модуле формы элемента справочника в обработчике ПриСозданииНаСервере скрываем элементы формы, если текущий пользователь не является ответственным менеджером:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	ЭтоСвойЭлемент = (Объект.Менеджер = ПараметрыСеанса.ТекущийПользователь)
		Или Не ЗначениеЗаполнено(Объект.Менеджер);
	
	Если Не ЭтоСвойЭлемент Тогда
		// Скрываем конфиденциальные поля формы
		Элементы.ГруппаКонтактнаяИнформация.Видимость = Ложь;
		Элементы.ГруппаКоммерческиеУсловия.Видимость = Ложь;
		Элементы.ОсновнойБанковскийСчет.Видимость = Ложь;
		
		// Блокируем редактирование чужого элемента
		ТолькоПросмотр = Истина;
	КонецЕсли;
	
КонецПроцедуры

2. В форме списка для динамического списка переопределяем текст запроса, обнуляя значения закрытых полей с помощью конструкции ВЫБОР:


ВЫБРАТЬ
	Контрагенты.Ссылка КАК Ссылка,
	Контрагенты.Наименование КАК Наименование,
	Контрагенты.ИНН КАК ИНН,
	Контрагенты.КПП КАК КПП,
	ВЫБОР
		КОГДА Контрагенты.Менеджер = &ТекущийПользователь ИЛИ Контрагенты.Менеджер = ЗНАЧЕНИЕ(Справочник.Пользователи.ПустаяСсылка)
			ТОГДА Контрагенты.Телефон
		ИНАЧЕ ""
	КОНЕЦ КАК Телефон
ИЗ
	Справочник.Контрагенты КАК Контрагенты

Вариант 3. Использование специальной формы просмотра

Если RLS по полям все же включен на уровне роли, для предотвращения ошибок при открытии формы элемента реализуем открытие отдельной не привязанной к объекту формы:

  1. В форме списка переопределяем событие динамического списка Выбор, устанавливая СтандартнаяОбработка = Ложь.
  2. Создаем отдельную форму обработки или общую форму, куда передаем ссылку на контрагента.
  3. В привилегированном режиме на сервере выполняем запрос к разрешенным полям объекта и заполняем реквизиты формы только теми данными, к которым у пользователя есть доступ.
← На главную