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