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