В процессе эксплуатации ERP-систем, таких как 1С:Управление производственным предприятием (УПП) ред. 1.3, часто возникает критически важная задача по обеспечению безопасности коммерческих данных. Типичный сценарий: руководство компании требует скрыть определенных контрагентов (например, ключевых покупателей) от большинства менеджеров, оставив им доступ только к поставщикам или рядовым клиентам. Это необходимо для предотвращения утечки клиентской базы, информации об объемах продаж и ценовой политике.
При этом ставится жесткое условие: нежелательный контрагент не должен фигурировать нигде — ни в списках справочников, ни в документах, ни в отчетах, ни в печатных формах. На практике стандартная настройка ограничений прав часто приводит к тому, что менеджеры все равно видят конфиденциальную информацию. Давайте разберем по шагам, как устроен этот механизм в 1С:УПП, проанализируем причины его "неработоспособности" в стандартных условиях и рассмотрим альтернативные программные решения.
Для реализации ограничения доступа на уровне записей в 1С:УПП используется типовой механизм ограничений. Рассмотрим подробнее, как его активировать и правильно настроить:
Сервис — Управление пользователями и доступом — Параметры настройки. На вкладке "Ограничение доступа" необходимо установить флаг напротив опции Контрагенты. Это действие инициализирует использование шаблонов RLS для справочника контрагентов в ролях конфигурации.
Группы доступа контрагентов. Нам нужно создать логические группы, разделяющие доступ. Например, создадим две группы: "Покупатели" (которые должны быть скрыты) и "Поставщики" (доступные всем).
Прочие и в реквизите Группа доступа контрагента укажем соответствующее значение. Обратите внимание: если у контрагента это поле останется пустым, то правила RLS могут интерпретировать это как отсутствие ограничений или, наоборот, полный запрет в зависимости от настроек логики прав.
Групп пользователей (справочник Группы пользователей). Откроем карточку группы пользователей (например, "Отдел продаж"), перейдем на вкладку Группы доступа контрагентов и добавим в список только те группы, к которым разрешен доступ (например, "Поставщики"). Группу "Покупатели" оставляем незаполненной и не добавленной в этот список.
Очень часто администраторы и программисты сталкиваются с ситуацией, когда после выполнения всех вышеуказанных шагов пользователь все равно продолжает видеть "скрытого" контрагента в отчетах по продажам или в документах реализации. Выясним причины такого поведения платформы.
В платформе "1С:Предприятие" действует строгое правило: если пользователю назначено несколько ролей или он входит в несколько групп пользователей, его итоговые права определяются как объединение прав по «ИЛИ». Рассмотрим ситуацию: пользователь входит в группу "Отдел продаж" (где закрыт доступ к VIP-клиентам) и в группу "Склад" (где ограничения по контрагентам вообще не настроены). В таком случае система предоставит пользователю полный доступ к контрагентам, так как одна из его групп разрешает это чтение. Проанализируем права пользователя и убедимся, что ограничения настроены во всех его группах пользователей единообразно.
Если у пользователя в списке назначенных ролей присутствует хотя бы одна роль, у которой на справочник Контрагенты установлено право Чтение или Просмотр без использования условий ограничения (шаблонов RLS), то вся система защиты обнуляется. Платформа видит, что одна из ролей позволяет читать данные без ограничений, и отключает проверки RLS для этого объекта. Нам необходимо тщательно проверить профиль полномочий пользователя и исключить любые роли, не содержащие условий RLS для контрагентов. Для этой задачи подойдёт инструмент для массового изменения ролей пользователей и профилей полномочий в 1С:УПП 1.3.
Это самая распространенная методическая ошибка. Настройка RLS только на справочник Контрагенты не гарантирует сокрытие информации. Если у пользователя открыт доступ на чтение к документам (например, РеализацияТоваровУслуг) или регистрам (например, регистр накопления Продажи или регистр бухгалтерии Хозрасчетный) без аналогичных ограничений, то:
<Объект не найден...>. По уникальному идентификатору (GUID), сопутствующим договорам или суммам менеджер все равно сможет понять, о какой сделке идет речь, что нарушает конфиденциальность.Для решения этой проблемы необходимо убедиться, что ограничения RLS настроены не только на сам справочник Контрагенты, но и на все связанные регистры, в которых присутствует измерение Контрагент или реквизит ДоговорКонтрагента.
Даже при идеальной настройке RLS в отчетах и списках, конфиденциальные данные могут отобразиться в печатных формах документов. Посмотрим на причину этого явления.
Большинство печатных форм в типовых конфигурациях 1С (и УПП здесь не исключение) формируются в так называемом привилегированном режиме. Этот режим временно отключает проверку прав доступа на уровне СУБД для того, чтобы выполнение сложных запросов и сборка макетов происходили быстро и без ошибок нехватки прав у рядовых пользователей. В результате, когда менеджер нажимает кнопку "Печать", код выполняется на сервере без учета RLS, и имя скрытого контрагента спокойно выводится на печать.
Чтобы избежать этой проблемы, требуется программная доработка общих модулей печати. Необходимо принудительно проверять права текущего пользователя на выводимый объект перед заполнением параметров макета, используя метод ПравоДоступа() или выполняя предварительный запрос без привилегированного режима.
Применение классического RLS в 1С:УПП имеет один огромный минус — критическое падение производительности. При активации ограничений к каждому SQL-запросу на чтение данных динамически добавляются тяжелые подзапросы (JOIN) с проверкой прав из регистра сведений ПраваДоступаПользователейКОбъектам.
На крупных информационных базах со множеством транзакций это приводит к следующим последствиям:
Если падение производительности из-за RLS неприемлемо для вашего бизнеса, мы можем прибегнуть к альтернативным и более "легким" методам фильтрации на уровне интерфейса и кода.
Рассмотрим пример, как ограничить показ документов по запрещенным контрагентам в формах списков динамически, используя обработчики событий обычных форм. В модуле формы списка справочника Контрагенты или списка документов вставим следующий код:
Процедура ПриОткрытии()
// Если у пользователя нет полных прав, устанавливаем жесткий отбор
Если НЕ РольДоступна("ПолныеПрава") Тогда
// Получаем список разрешенных групп доступа для текущего пользователя
СписокРазрешенныхГрупп = ПолучитьСписокРазрешенныхГруппДоступа();
// Накладываем отбор на табличное поле списка
ЭлементОтбора = СправочникСписок.Отбор.ГруппаДоступа;
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = СписокРазрешенныхГрупп;
ЭлементОтбора.Использование = Истина;
// Запрещаем пользователю изменять этот отбор вручную
ЭлементОтбора.Доступность = Ложь;
КонецЕсли;
КонецПроцедуры
Чтобы предотвратить вывод закрытых контрагентов в отчетах, мы можем программно модифицировать настройки компоновщика данных перед выводом результата. Разберем по шагам, как это реализовать в модуле объекта отчета:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
Если НЕ РольДоступна("ПолныеПрава") Тогда
// Получаем массив контрагентов, которые должны быть скрыты от текущего пользователя
ЗапрещенныеКонтрагенты = ПолучитьСписокЗапрещенныхКонтрагентов();
Если ЗапрещенныеКонтрагенты.Количество() > 0 Тогда
// Добавляем элемент отбора по контрагенту в настройки СКД
НовыйОтбор = КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент");
НовыйОтбор.ВидСравнения = ВидСравнения.НеВСписке;
НовыйОтбор.ПравоеЗначение = ЗапрещенныеКонтрагенты;
НовыйОтбор.Использование = Истина;
// Делаем настройку недоступной для изменения пользователем в режиме предприятия
НовыйОтбор.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.Недоступный;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Для предотвращения несанкционированного ввода документов по скрытым контрагентам (даже если пользователь попытается обойти интерфейс или использовать внешние обработки) мы можем использовать подписку на событие ПередЗаписью для всех видов документов, где фигурирует контрагент:
Процедура ПроверитьПраваНаКонтрагентаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Если НЕ РольДоступна("ПолныеПрава") Тогда
// Проверяем реквизит "Контрагент" документа
Если ОбщегоНазначения.ЕстьРеквизитОбъекта("Контрагент", Источник.Метаданные()) Тогда
ТекущийКонтрагент = Источник.Контрагент;
Если ЗначениеЗаполнено(ТекущийКонтрагент) И НЕ ДоступРазрешен(ТекущийКонтрагент) Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("У вас нет прав на работу с контрагентом: " + ТекущийКонтрагент);
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Для полной и гарантированной конфиденциальности отдельных элементов справочника контрагентов в 1С:УПП необходим комплексный подход. Стандартный механизм RLS решает эту задачу "из коробки", но требует тщательной настройки групп пользователей, исключения конфликтующих ролей и применения ограничений к регистрам. Если же в приоритете стоит высокая производительность базы данных, оптимальным решением станет использование программной фильтрации на уровне динамических списков форм, СКД в отчетах и жесткого контроля записи через подписки на события. При необходимости можно использовать пример настройки роли менеджера по продажам в 1С:УПП с помощью RLS и кода.