Как в 1С разделить права на чтение и просмотр записей (RLS) для разных организаций?

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

Разберем классическую задачу при настройке прав доступа: необходимо сделать так, чтобы пользователь мог видеть и полноценно работать с документами только по одной организации (Организация А), а по второй организации (Организация Б) программа должна иметь возможность только читать документы (например, для проведения расчетов или проводок), но сам пользователь в списках их видеть не должен.

Часто разработчики пытаются решить эту задачу созданием двух профилей групп доступа: в первом выдаются права на чтение и просмотр для Организации А, во втором — роль ТОЛЬКО с правом на чтение для Организации Б. Однако при запуске в режиме «Предприятие» пользователь видит в журналах документы по обеим организациям. Проанализируем причину такого поведения и рассмотрим корректные пути решения.

Почему платформа 1С объединяет права на просмотр?

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

  1. Суммирование прав по принципу «ИЛИ». Права из всех ролей, назначенных пользователю, складываются. Если первая роль дает права «Чтение» и «Просмотр» для Организации А, а вторая роль — только «Чтение» для Организации Б, платформа применит право «Просмотр» ко всем данным, которые пользователю разрешено читать.
  2. Ограничения механизма RLS. Настроить RLS можно только на базовые операции с базой данных: Чтение, Добавление, Изменение и Удаление. Право на Просмотр не имеет своего RLS. Это производное интерактивное право, которое предоставляется на объект метаданных в целом. Следовательно, вы сможете просматривать всё, что система позволила вам прочитать.

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

Решение 1: Использование привилегированного режима (Рекомендуемый подход)

Вместо того чтобы пытаться выдать пользователю «невидимые» права на чтение документов по Организации Б, полностью исключите эту организацию из его групп доступа. Документы второй организации не будут читаться под правами пользователя, а значит, и не отобразятся в интерфейсе.

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

Посмотрим на пример, как это можно реализовать в коде:


УстановитьПривилегированныйРежим(Истина);

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

Запрос.УстановитьПараметр("ОрганизацияБ", ТребуемаяОрганизация);
Результат = Запрос.Выполнить().Выгрузить();

УстановитьПривилегированныйРежим(Ложь);

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

Решение 2: Программное скрытие в интерфейсе списков

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

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = РазрешеннаяОрганизация; // Организация А
    ЭлементОтбора.Использование = Истина;
    ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
    
КонецПроцедуры

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

Решение 3: Выделение данных в независимый регистр

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

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

Решение 4: Выполнение операций под служебным пользователем

Если программное чтение инициализируется не действиями самого пользователя в интерфейсе, а внешними событиями (регламентные задания, веб-сервисы, HTTP-сервисы), то такие операции настраиваются на выполнение под отдельным системным пользователем.

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

← На главную