В этой статье мы подробно разберем, как реализовать ограничение прав пользователя с полными правами (администратора) на изменение определенных данных в системе 1С, при этом сохранив его возможность управлять пользователями, ролями и другими административными функциями. Эта задача является одной из самых сложных в системе безопасности 1С, поскольку пользователь с полными правами по умолчанию имеет доступ ко всем данным и обходит большинство ограничений. Мы рассмотрим несколько подходов и выясним их преимущества и недостатки.
Мы выясним, почему стандартная роль "Полные права" не поддается ограничениям RLS и как это обойти, создав новую административную роль с ограниченным доступом к данным.
Понимание ограничений роли "Полные права": Мы должны осознать, что пользователь с ролью ПолныеПрава имеет неограниченный доступ ко всем данным в системе и автоматически обходит все ограничения на уровне записей (RLS). Это означает, что прямое применение RLS к пользователю с ролью "Полные права" не принесет желаемого результата. Поэтому для реального ограничения администратора нам необходимо создать нового пользователя, который не будет иметь эту роль.
Создание новой роли "Технический администратор": Мы создадим новую роль в конфигурации, назовем ее, например, ТехническийАдминистратор. Эта роль будет использоваться для пользователя, который будет выполнять административные функции, но не сможет напрямую изменять оперативные данные. Для этого мы открываем конфигуратор, переходим в раздел "Роли" и добавляем новую роль.
Предоставление административных прав новой роли: Для роли ТехническийАдминистратор мы предоставим права на работу с административными объектами, такими как:
Справочник.Пользователи: разрешение на чтение, добавление, изменение, удаление.Справочник.ПрофилиГруппДоступа: разрешение на чтение, добавление, изменение, удаление.Справочник.ГруппыДоступа: разрешение на чтение, добавление, изменение, удаление.РегистрСведений.НазначениеПравДоступа: разрешение на чтение, добавление, изменение, удаление.ПланыОбмена, если нашему техническому администратору необходимо управлять синхронизацией данных.Важный момент: Мы сознательно не будем давать этой роли права на чтение, изменение, добавление, удаление (Чтение, Изменение, Добавление, Удаление) для тех объектов конфигурации (документов, справочников, регистров), которые мы хотим защитить от интерактивных изменений.
Применение RLS для дополнительного контроля (при необходимости): Хотя новая роль сама по себе не имеет прав на защищаемые объекты, мы можем применить RLS для этой роли, если хотим ввести более тонкие ограничения, например, на просмотр определенных данных, или на модификацию *только* определенных наборов данных внутри разрешенных объектов. Для этого в свойствах роли ТехническийАдминистратор для соответствующих объектов устанавливаем ограничения на уровне записей.
Например, рассмотрим ситуацию, когда роль ТехническийАдминистратор имеет право на чтение справочника Номенклатура, но мы хотим ограничить просмотр некоторых элементов. В этом случае мы можем настроить RLS:
#ПоЗначениям("Справочник.Номенклатура", "Просмотр", "ГДЕ Не Номенклатура.ПометкаУдаления")
Это позволит просматривать только не помеченные на удаление элементы. Однако помните, что основное ограничение на изменение достигается именно отсутствием прав на Чтение/Изменение, а не только RLS, который регулирует доступ к записям.
Создание пользователя и назначение новой роли: Мы создадим нового пользователя в системе (например, "Технический Администратор") и назначим ему только роль ТехническийАдминистратор (или комбинацию этой роли с другими ролями, не дающими полных прав, которые ему необходимы). Этот пользователь сможет выполнять административные действия, но не сможет напрямую изменять защищенные данные в объектах, на которые ему не выданы права.
Мы рассмотрим, как программно запретить запись определенных объектов даже для администраторов, используя подписки на события и проверки в общих модулях. Этот метод позволяет вмешиваться в процесс записи объектов, независимо от назначенных ролей.
Подписки на события ПриЗаписи / ПередЗаписью: Этот метод позволяет перехватывать попытки записи объектов в базу данных и программно запрещать их. Мы будем использовать подписку на событие, например, для объекта Документ.РеализацияТоваровУслуг или РегистрСведений.ЦеныНоменклатуры.
Создание подписки: Мы создадим новую подписку на событие ПриЗаписи или ПередЗаписью для требуемых объектов. Для этого в конфигураторе перейдем в раздел "Подписки на события", добавим новую, укажем имя, событие (например, "ПриЗаписи"), источник (тип объекта, например, ДокументОбъект.РеализацияТоваровУслуг) и приемник (общий модуль, например, УправлениеПравамиАдминистратора) и метод (функция внутри этого общего модуля, например, ПриЗаписиДокументаРеализацияТоваровУслуг).
Реализация обработчика подписки: В созданном общем модуле мы реализуем функцию-обработчик. В этой функции мы можем проверить, кто пытается записать объект (например, используя ТекущийПользователь или РольДоступна("ПолныеПрава")), и если это администратор, запретить запись.
Посмотрим на пример кода для обработчика подписки, который может быть размещен в общем модуле УправлениеПравамиАдминистратора:
// Обработчик события ПриЗаписи для Документа.РеализацияТоваровУслуг
// Источник - это Объект, Отказ - булево.
Процедура ПриЗаписиДокументаРеализацияТоваровУслуг(Источник, Отказ) Экспорт
// Объект - это ДокументОбъект.РеализацияТоваровУслуг, который сейчас записывается.
// Проверим, является ли текущий пользователь администратором,
// то есть имеет ли роль "ПолныеПрава".
// Исключаем случаи программной записи, если администратору это явно разрешено.
Если РольДоступна("ПолныеПрава") ИЛИ Пользователи.Администратор Тогда
Если Не Источник.ДополнительныеСвойства.Свойство("ПрограммнаяЗаписьАдминистратором") Тогда
// Здесь мы можем ввести дополнительную логику.
// Например, запрещать запись только если документ новый
// (Источник.ЭтоНовый()) или если изменяются определенные реквизиты.
// Для примера, просто запрещаем запись для администратора,
// если это не специальная программная запись.
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = НСтр("ru = 'Администратору запрещено интерактивное изменение документа ""Реализация товаров и услуг"". Обратитесь к разработчикам для внесения изменений.'");
Сообщение.Поле = "Номер"; // Можно указать конкретное поле для указания на ошибку
Сообщение.УстановитьОбъект(Источник);
Сообщение.Сообщить();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Обратите внимание, что в примере мы добавили проверку Не Источник.ДополнительныеСвойства.Свойство("ПрограммнаяЗаписьАдминистратором"). Это позволяет нам предусмотреть сценарии, когда администратору все же необходимо программно записать документ, обойдя это ограничение. В таком случае перед вызовом метода Записать() администраторский код мог бы добавить это свойство в ДополнительныеСвойства объекта:
ДокументОбъект.ДополнительныеСвойства.Вставить("ПрограммнаяЗаписьАдминистратором", Истина);
ДокументОбъект.Записать();
ДокументОбъект.ДополнительныеСвойства.Удалить("ПрограммнаяЗаписьАдминистратором"); // Удаляем свойство после записи
Такой подход обеспечивает контролируемый обход запрета для администратора в особых случаях.
Использование расширений для подписок: Мы настоятельно рекомендуем реализовывать такие подписки на события не напрямую в основной конфигурации, а в расширении. Это позволит сохранить конфигурацию на поддержке и упростит обновление.
Действия: Мы создаем новое расширение, добавляем в него нужную подписку на событие и общий модуль с обработчиком. После этого расширение публикуется. Таким образом, мы добавляем новую функциональность, не изменяя типовое решение.
Проверки в общих модулях: Мы можем реализовать аналогичные проверки напрямую в тех общих модулях, которые выполняют запись объектов. Например, в общих модулях, отвечающих за проведение документов (таких как ДокументыОбщие.ПередЗаписьюДокумента()).
Процедура ПередЗаписьюДокумента(Объект, Отказ, РежимЗаписи, РежимПроведения) Экспорт
Если ТипЗнч(Объект) = Тип("ДокументОбъект.РеализацияТоваровУслуг") Тогда
Если РольДоступна("ПолныеПрава") ИЛИ Пользователи.Администратор Тогда
// Здесь можно добавить более детальные проверки,
// например, проверять, какие именно поля были изменены.
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = НСтр("ru = 'Администратору запрещено изменение данного документа через этот обработчик.'");
Сообщение.УстановитьОбъект(Объект);
Сообщение.Сообщить();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Этот подход менее универсален, чем подписки, так как требует модификации существующего кода в общих модулях. Однако в некоторых случаях он может быть более точным, если нам нужен контроль над конкретными операциями, выполняемыми этими модулями, и нет возможности использовать подписки (например, если код вызывается из системного функционала, который не инициирует события ПриЗаписи).
Мы рассмотрим более простой, но менее гибкий метод, который может помочь в некоторых сценариях, особенно для регистров сведений и других объектов, которые не должны редактироваться напрямую.
Настройка свойства "Запретить интерактивное изменение": Для некоторых объектов конфигурации (например, для регистров сведений, реквизитов справочников или документов), мы можем установить свойство "Запретить интерактивное изменение" (ИнтерактивноеИзменениеЗапрещено в свойствах объекта). Это означает, что пользователь не сможет открыть форму списка или форму элемента для прямого редактирования.
Для регистров сведений это свойство находится на вкладке "Данные" в свойствах самого регистра. Для реквизитов — в свойствах реквизита на вкладке "Дополнительно".
Как это влияет на администратора: Даже администратор не сможет интерактивно изменить данные в таких объектах через стандартные формы. Изменение будет возможно только программно, то есть через код или обработки, которые обходят интерактивное редактирование. Это может быть полезно, если нам нужно, чтобы администратор мог влиять на данные только через специально разработанные обработки или функции, но не напрямую.
Ограничения подхода: Этот метод не блокирует программные изменения. Администратор все равно может написать обработку или выполнить код в консоли запросов/кода, чтобы изменить данные. Он лишь ограничивает "быстрое" интерактивное редактирование, что является важным, но не исчерпывающим уровнем защиты.
Хотя функциональные опции не предназначены напрямую для ограничения прав администратора, мы можем использовать их в качестве части более сложной системы для управления видимостью и доступностью функционала.
Назначение функциональных опций: Мы можем создать функциональную опцию, которая управляет видимостью или доступностью определенных форм или команд, связанных с изменением критичных данных. Например, функциональная опция "Использование цен номенклатуры" может управлять видимостью команды для открытия формы списка цен.
Применение: Затем мы можем управлять этой опцией через роли. Для роли ТехническийАдминистратор мы можем отключить функциональную опцию, которая открывает доступ к форме редактирования цен номенклатуры, или делает видимой команду для изменения определенных критичных параметров. Это косвенный метод, который работает в комбинации с первым подходом (создание специализированной роли). Он помогает скрыть или сделать недоступным определенный функционал, но не запрещает изменение данных, если к ним можно получить доступ другими способами.
Мы должны всегда помнить о фундаментальном принципе безопасности в 1С при работе с административными правами:
Истинный администратор всегда может обойти ограничения: Пользователь, имеющий полный доступ к файлам базы данных или серверу, может отключить подписки на события, изменить код, или напрямую отредактировать данные минуя платформу 1С. Рассматриваемые нами методы направлены на ограничение действий администратора в рамках штатного интерфейса и программного кода конфигурации. Если администратор имеет доступ к файлам БД или конфигурированию, он всегда найдет способ обойти введенные ограничения.
Использование расширений — лучшая практика: Для внедрения программных ограничений (подписок на события) мы настоятельно рекомендуем использовать расширения. Это существенно облегчает поддержку и обновление конфигурации, так как позволяет избежать модификации типового кода.
Комбинирование подходов: Самый надежный подход часто заключается в комбинации методов. Мы можем создать специализированную роль для "технического администратора" (Подход 1) и дополнительно защитить наиболее критичные объекты программными проверками через подписки на события (Подход 2). Это создает многоуровневую систему защиты.
Документирование решений: Мы всегда должны документировать примененные решения, особенно если они затрагивают базовые механизмы безопасности. Это поможет в будущем при поддержке и развитии системы, а также обеспечит прозрачность внесенных изменений.
Итак, мы рассмотрели несколько эффективных способов ограничения прав администратора на изменение данных в 1С. Выбор конкретного подхода или их комбинации зависит от ваших требований к безопасности, сложности конфигурации и уровня доверия к администраторам системы. Мы рекомендуем тщательно анализировать каждый сценарий и применять наиболее подходящие решения, помня о принципиальных ограничениях платформы 1С в части защиты от "всемогущего" администратора.