При настройке прав доступа в 1С:Предприятие часто возникает классическая дилемма: пользователю необходимо ограничить видимость остатков и документов только "его" складом, но при этом оставить возможность создавать документы Перемещение товаров, где в качестве склада-получателя может выступать любой склад компании. Если стандартный механизм RLS (Record Level Security) настроен на справочник Склады, то при попытке выбрать склад-получатель пользователь просто не увидит другие склады в списке, а в существующих документах вместо названий будет отображаться надпись "Объект не найден".
В этой статье мы подробно проанализируем ситуацию и разберем несколько эффективных способов решения этой задачи, начиная от изменения архитектуры прав и заканчивая использованием расширений платформы.
Когда мы устанавливаем ограничение на чтение справочника Склады, платформа 1С фильтрует записи на уровне SQL-запроса. Если условие RLS не выполняется для конкретной записи, то для системы этой записи "не существует" для текущего пользователя. Это влечет за собой две основные проблемы:
Рассмотрим подробнее способы обхода этих ограничений, которые позволяют сохранить безопасность данных и обеспечить удобство работы.
Проанализируем стратегию настройки прав. В большинстве случаев бизнес-задача звучит так: "Пользователь не должен видеть остатки на чужих складах". Это не означает, что он не должен знать о существовании самого склада как элемента справочника.
Самый правильный и технологичный способ в типовых конфигурациях (ERP, КА, УТ) — это снять ограничение RLS со справочника Склады и перенести его на регистры накопления (например, Товары на складах, Выручка и себестоимость продаж) и документы.
Как это реализовать по шагам:
Склады право Чтение предоставлено без ограничений (поле RLS пустое или содержит ГДЕ ИСТИНА).Если по каким-то причинам вы не можете изменить общую схему RLS (например, политика компании запрещает видеть даже названия чужих складов в общих списках), можно использовать механизм расширений для точечного обхода системы прав в конкретном документе.
Суть метода заключается в том, чтобы перехватить момент выбора склада и подменить стандартную форму выбора своей, которая работает в привилегированном режиме.
Разберем пример кода для расширения формы документа ПеремещениеТоваров:
&НаКлиенте
Процедура Расш_СкладПолучательНачалоВыбораПосле(Элемент, ДанныеВыбора, СтандартнаяОбработка)
// Отменяем стандартное открытие формы выбора
СтандартнаяОбработка = Ложь;
// Параметры для открытия нашей формы
ПараметрыВыбора = Новый Структура;
ПараметрыВыбора.Вставить("РежимВыбора", Истина);
// Открываем форму выбора склада, игнорируя текущий RLS
ОткрытьФорму("Справочник.Склады.ФормаВыбора", ПараметрыВыбора, Элемент);
КонецПроцедуры
Однако просто открыть форму недостаточно. Чтобы форма выбора показала все склады, в ее модуле или в серверном вызове необходимо установить привилегированный режим. Выясним причину: даже если вы открыли форму программно, запрос внутри нее все равно будет ограничен RLS пользователя. Поэтому список складов нужно формировать через запрос на сервере с использованием УстановитьПривилегированныйРежим(Истина).
В платформе 1С 8.3 права доступа суммируются по принципу ИЛИ. Если у пользователя есть две роли: одна запрещает чтение складов (RLS), а вторая разрешает чтение всех складов (без RLS), то в итоге пользователю будет разрешено чтение всех складов.
Посмотрим на алгоритм действий:
ЧтениеСкладовБезОграничений.Склады установите право Чтение (Read) и Просмотр (View).Важный нюанс: Этот способ сделает все склады видимыми во всех документах и списках. Если ваша задача — разрешить выбор только в перемещении, этот метод может быть избыточным.
Для того чтобы пользователь мог вводить название склада в поле ввода и система находила его (автоподбор), можно использовать механизм ОбработкаПолученияДанныхВыбора в модуле менеджера справочника Склады. Это позволяет переопределить стандартный поиск 1С.
Рассмотрим пример кода в модуле менеджера:
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
// Если нам нужно обойти RLS только в конкретных случаях
Если Параметры.Свойство("ОбойтиRLS") И Параметры.ОбойтиRLS Тогда
СтандартнаяОбработка = Ложь;
УстановитьПривилегированныйРежим(Истина);
// Выполняем запрос к справочнику без учета прав
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ Ссылка, Наименование ИЗ Справочник.Склады ГДЕ Наименование ПОДОБНО &Текст";
Запрос.УстановитьПараметр("Текст", Параметры.СтрокаПоиска + "%");
// Формируем таблицу результатов
ДанныеВыбора = Новый СписокЗначений;
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ДанныеВыбора.Добавить(Выборка.Ссылка, Выборка.Наименование);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Проанализируем ситуацию: даже если вы позволили пользователю выбрать склад с помощью кода, после записи документа он может увидеть "Объект не найден" в поле склада-получателя. Это происходит потому, что право Просмотр (View) все еще ограничено RLS.
Чтобы название склада отображалось корректно, у пользователя обязательно должно быть право Чтение (Read) на этот объект. Если вы используете жесткий RLS на чтение, 1С физически не может получить представление объекта из базы.
Решение: Используйте "мягкий" RLS. Вместо полной блокировки чтения элемента справочника, настройте RLS так, чтобы чтение было разрешено всегда (для отображения представления), а вот доступ к связанным данным (остаткам) был закрыт. В современных версиях БСП для этого используется "Производительный режим RLS", который позволяет гибко управлять доступом через таблицы групп доступа.
Подводя итог, выберем оптимальный путь решения проблемы в зависимости от ситуации:
НачалоВыбора и программным открытием формы в привилегированном режиме.Выбор конкретного метода зависит от требований безопасности вашей организации, но с точки зрения архитектуры 1С, первый способ является наиболее предпочтительным и "чистым".