Приветствуем вас! В процессе разработки и сопровождения конфигураций на платформе «1С:Предприятие» перед нами нередко встает задача тонкой настройки прав доступа к данным. Типичный сценарий: пользователю необходимо предоставить возможность изменять лишь одно-единственное поле в элементе справочника (например, статус, отметку о проверке или комментарий), в то время как все остальные реквизиты должны оставаться строго защищенными от редактирования. В этой статье мы подробно разберем, как решить эту задачу, проанализируем различные подходы — от классических ролей до современных механизмов БСП — и выясним, почему популярная технология RLS в данном контексте работает не так, как многие ожидают.
Когда разработчики сталкиваются с необходимостью разграничить права доступа на уровне отдельных полей, первым делом на ум приходит технология RLS (безопасность на уровне записей). Действительно, платформа «1С:Предприятие» предоставляет мощные инструменты для фильтрации данных с помощью запросов RLS. Однако при детальном рассмотрении мы сталкиваемся с критическими техническими ограничениями этого механизма:
Чтение. Например, вы можете успешно скрыть конфиденциальную колонку «Оклад» в справочнике сотрудников для определенных ролей. При попытке применить аналогичный подход к праву Изменение система ведет себя иначе.Изменение через RLS накладывается на всю строку (запись) таблицы целиком. Платформа не умеет частично записывать объект в базу данных. Либо элемент справочника обновляется полностью, либо транзакция отменяется.Таким образом, попытка решить задачу исключительно средствами RLS для права Изменение заведомо обречена на неудачу. Нам необходимо рассмотреть альтернативные и более надежные способы.
Самым простым и быстрым способом, не требующим написания сложного программного кода, является настройка прав непосредственно в объекте метаданных Роль через Конфигуратор. Разберем этот процесс по шагам:
Роли, добавим новую роль или откроем для редактирования существующую (например, созданную специально для наших ограничений).Интерактивное изменение и права на конкретные реквизиты.Редактирование для всех реквизитов, кроме того единственного, который пользователю разрешено изменять. Для разрешенного реквизита оставим права активными.Несмотря на кажущуюся простоту, этот метод таит в себе две серьезные проблемы, которые могут полностью нарушить логику работы информационной системы:
Проблема 1: Принцип объединения ролей по «ИЛИ». В экосистеме 1С права пользователя формируются путем сложения всех назначенных ему ролей. Если у нашего пользователя, помимо созданной роли с ограничениями, есть хотя бы одна стандартная роль (например, «Кадровик» или «Бухгалтер»), в которой разрешено изменение всего справочника, то наше ограничение попросту не сработает. Система увидит, что в другой роли изменение разрешено, и предоставит пользователю полный доступ. Чтобы ограничение сработало, придется убирать право на изменение этих реквизитов во всех остальных ролях пользователя, что крайне затруднительно в типовых конфигурациях.
Проблема 2: Ошибки при записи объекта. Когда у роли отключено право редактирования большинства реквизитов, но разрешена интерактивная запись самого объекта, платформа может выбросить исключение нарушения прав доступа при попытке сохранить элемент. Это связано с тем, что при записи объекта в базу данных система пытается перезаписать всю строку целиком, включая те поля, на которые у пользователя нет прав редактирования. Платформа не всегда корректно обрабатывает такие ситуации, особенно если логика записи включает проведение сопутствующих документов или программное заполнение служебных реквизитов.
Если мы работаем в современных конфигурациях на платформе 1С (таких как ERP, Комплексная автоматизация, Управление торговлей 11 или Зарплата и управление персоналом 3), нам доступен готовый инструмент из состава Библиотеки стандартных подсистем (БСП). Этот механизм позволяет гибко управлять доступностью полей на форме без вмешательства в структуру ролей.
Суть механизма заключается в том, что для ключевых реквизитов справочника или документа, изменение которых может нарушить целостность учета, настраивается автоматическая блокировка на форме элемента после его первой записи. Посмотрим, как это выглядит для конечного пользователя:
Еще — Разрешить редактирование реквизитов.Этот подход является наиболее цивилизованным и поддерживаемым, однако он требует наличия БСП в конфигурации и правильной интеграции объектов со стандартными механизмами библиотеки.
В тех случаях, когда мы работаем с устаревшими конфигурациями (например, ЗУП КОРП 2.5, упомянутой в исходном обсуждении на форуме) или нам требуется внедрить жесткий, независимый от интерфейса контроль, на помощь приходит программный код. Мы можем реализовать защиту на двух уровнях: на уровне базы данных (транзакции записи) и на уровне пользовательского интерфейса (формы объекта).
Шаг 1: Контроль на уровне базы данных через подписку на события
Это самый надежный способ защиты информации. Он сработает независимо от того, как именно пользователь пытается изменить реквизит — интерактивно через форму, программно с помощью внешней обработки или через групповое изменение реквизитов. Нам потребуется создать подписку на событие ПередЗаписью для интересующего нас справочника.
Рассмотрим пример кода, который предотвратит запись изменений любых реквизитов, кроме разрешенного реквизита ВажноеПоле:
Процедура ПроверитьИзменениеРеквизитовПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Если объект новый, разрешаем запись без ограничений
Если Источник.ЭтоНовый() Тогда
Возврат;
КонецЕсли;
// Проверяем, есть ли у пользователя роль-ограничение
Если РольДоступна("ОграниченнаяРольНаИзменение") Тогда
// Получаем текущее состояние объекта из базы данных напрямую по ссылке
СтарыйОбъект = Источник.Ссылка;
// Перебираем все реквизиты объекта для сравнения старых и новых значений
Для Каждого Реквизит Из Источник.Метаданные().Реквизиты Цикл
// Пропускаем наш единственный разрешенный для изменения реквизит
Если Реквизит.Имя = "ВажноеПоле" Тогда
Продолжить;
КонецЕсли;
// Сравниваем старое значение из БД и новое значение из памяти
Если Источник[Реквизит.Имя] <> СтарыйОбъект[Реквизит.Имя] Тогда
Отказ = Истина;
ВызватьИсключение "У вас нет прав на изменение реквизита '" + Реквизит.Синоним + "'. Разрешено редактировать только 'ВажноеПоле'.";
Прервать;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Шаг 2: Управление доступностью полей на уровне формы
Чтобы пользователь не получал раздражающую ошибку только в момент нажатия кнопки «Записать», крайне желательно визуально заблокировать недоступные поля непосредственно при открытии формы элемента. Для этого в модуле формы (в процедуре ПриОткрытии для обычных форм или ПриСозданииНаСервере для управляемых форм) мы можем программно отключить доступность элементов управления.
Давайте проанализируем пример кода для управляемой формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем наличие ограничивающей роли у текущего пользователя
Если РольДоступна("ОграниченнаяРольНаИзменение") Тогда
// Обходим все элементы формы
Для Каждого ЭлементФормы Из Элементы Цикл
// Нам нужно заблокировать только поля ввода, связанные с реквизитами объекта
Если ТипЗнч(ЭлементФормы) = Тип("ПолеФормы") И ЭлементФормы.Вид = ВидПоляФормы.ПолеВвода Тогда
// Проверяем путь к данным элемента
ПутьКДанным = ЭлементФормы.ПутьКДанным;
// Если поле связано с реквизитом объекта, но это не наше разрешенное поле
Если Найти(ПутьКДанным, "Объект.") > 0 И Найти(ПутьКДанным, "ВажноеПоле") = 0 Тогда
ЭлементФормы.Доступность = Ложь;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Совместное использование подписки на событие ПередЗаписью и программного отключения доступности полей на форме дает гарантированный результат: пользователь наглядно видит, какие поля ему запрещено редактировать, а СУБД надежно защищена от любых несанкционированных обходов интерфейса через внешние обработки.
Для реализации ограничения на изменение реквизитов объекта в 1С мы имеем несколько инструментов с разной степенью надежности: