Проверка ролей текущего пользователя в 1С 8.3: функции платформы, БСП и запросы

· 9 мин

Содержание

Быстрее всего узнать роль текущего пользователя в 1С функцией глобального контекста РольДоступна(Метаданные.Роли.ИмяРоли): она возвращает Истина, если у сеанса есть эта роль. Работает и на клиенте, и на сервере, вызова сервера не требует. Полный список ролей даёт серверный код: ПользователиИнформационнойБазы.ТекущийПользователь().Роли.

Всё остальное — уточнения под задачу. В типовых конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) роли раздаются через профили групп доступа, и там удобнее функции общего модуля Пользователи. А если вопрос не «есть ли роль», а «можно ли читать этот справочник», правильнее проверять право, а не роль.

Ниже код для платформы 8.3 с управляемым интерфейсом. Всё, что относится к платформе, работает в любой конфигурации; всё, что относится к БСП, — только там, где подключена Библиотека стандартных подсистем.

Роль текущего пользователя через глобальный контекст

Платформа даёт два основных инструмента. Они отвечают на разные вопросы.

ИнструментЧто возвращаетГде доступен
РольДоступна(Роль)Булево: есть ли одна конкретная рольКлиент и сервер
ПользователиИнформационнойБазы.ТекущийПользователь().РолиКоллекция всех ролей пользователяСервер, толстый клиент, внешнее соединение
ИмяПользователя(), ПолноеИмяПользователя()Имя пользователя ИБ, строкаКлиент и сервер

Функция РольДоступна

Параметр — объект метаданных роли или строка с именем роли. Через метаданные надёжнее: опечатку в имени поймает синтаксический контроль, а строку — нет.

Если РольДоступна(Метаданные.Роли.ПолныеПрава) Тогда
    Элементы.ГруппаАдминистрирование.Видимость = Истина;
КонецЕсли;

Типичное место для такой проверки — ПриСозданииНаСервере формы: скрыть кнопку, сделать поле только для просмотра, поменять отбор списка.

На клиенте РольДоступна вызывается без обращения к серверу. Поэтому её можно смело использовать в обработчиках команд формы, не боясь лишних серверных вызовов.

Коллекция ролей пользователя ИБ

Когда нужен весь набор ролей — например, вывести его в отладочное сообщение или записать в журнал — используйте менеджер пользователей информационной базы. Он есть только на сервере, поэтому в форме понадобится серверная процедура.

&НаСервереБезКонтекста
Функция РолиТекущегоПользователя()

    Результат = Новый Массив;
    ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();

    Для Каждого Роль Из ПользовательИБ.Роли Цикл
        Результат.Добавить(Роль.Имя);
    КонецЦикла;

    Возврат Результат;

КонецФункции

Проверить одну роль в этой коллекции можно методом Содержит:

ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
ЕстьПолныеПрава = ПользовательИБ.Роли.Содержит(Метаданные.Роли.ПолныеПрава);

Разница принципиальная: коллекция Роли показывает, что записано в настройках пользователя, а РольДоступна — что реально доступно в текущем сеансе. В обычных условиях ответы совпадают. Расхождения появляются в особых случаях, о них ниже.

Сведения о ролях в типовых конфигурациях на БСП

В Бухгалтерии, ЗУП, УТ и других конфигурациях на БСП администратор не ставит галочки ролей вручную. Он включает пользователя в группу доступа, а у группы есть профиль со списком ролей. Платформенные роли пользователю ИБ проставляет сама БСП.

Посмотреть это в интерфейсе можно в разделе Администрирование → Настройки пользователей и прав: там списки пользователей, групп доступа и профилей групп доступа. В карточке пользователя есть переход к его правам доступа.

Функции общего модуля Пользователи

В коде БСП удобнее, чем голая платформа: функции учитывают полноправного пользователя и привилегированный режим.

ФункцияЧто делает
Пользователи.ТекущийПользователь()Ссылка на элемент справочника Пользователи
Пользователи.АвторизованныйПользователь()Пользователь или внешний пользователь текущего сеанса
Пользователи.ЭтоПолноправныйПользователь()Истина для администратора с полными правами
Пользователи.РолиДоступны("Роль1, Роль2")Истина, если доступна хотя бы одна из ролей

Пример проверки на сервере:

Если Пользователи.РолиДоступны("ДобавлениеИзменениеДанныхБухгалтерии, ПолныеПрава") Тогда
    // разрешаем редактирование
КонецЕсли;

Имена ролей здесь условные — подставьте роли своей конфигурации. Посмотреть их можно в Конфигураторе, ветка Общие → Роли.

Запрос к группам доступа

Иногда нужна не платформенная роль, а то, как права выданы на уровне прикладных данных: в каких группах доступа состоит пользователь и какие роли входят в их профили. Это запрос к справочникам БСП.

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
|    ГруппыДоступаПользователи.Ссылка КАК ГруппаДоступа,
|    ГруппыДоступаПользователи.Ссылка.Профиль КАК Профиль,
|    ПрофилиРоли.Роль КАК Роль
|ИЗ
|    Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
|        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПрофилиГруппДоступа.Роли КАК ПрофилиРоли
|        ПО ГруппыДоступаПользователи.Ссылка.Профиль = ПрофилиРоли.Ссылка
|ГДЕ
|    ГруппыДоступаПользователи.Пользователь = &Пользователь
|    И НЕ ГруппыДоступаПользователи.Ссылка.ПометкаУдаления";
Запрос.УстановитьПараметр("Пользователь", Пользователи.ТекущийПользователь());
Выборка = Запрос.Выполнить().Выбрать();

Поле Роль в профиле — ссылка на справочник идентификаторов объектов метаданных, а не сам объект метаданных.

Запрос ловит только прямое членство. Если в группу доступа включена группа пользователей, а не сам пользователь, он в выборку не попадёт. Структура справочников БСП меняется между редакциями библиотеки: перед использованием сверьте имена таблиц и реквизитов в своём Конфигураторе.

Для проверки «может ли человек что-то сделать прямо сейчас» этот запрос не подходит. Он отражает настройки, а не состояние сеанса. Для решения в коде используйте РольДоступна или функции модуля Пользователи.

Право доступа вместо роли и профили безопасности

Проверка конкретной роли хрупкая. Разработчик завтра разделит роль на две — и все условия РольДоступна(Метаданные.Роли.Старая) перестанут работать. Если важно действие, а не название роли, проверяйте право.

Функция ПравоДоступа

Если ПравоДоступа("Изменение", Метаданные.Справочники.Номенклатура) Тогда
    // пользователь может менять номенклатуру
КонецЕсли;

Первый параметр — имя права строкой: "Чтение", "Добавление", "Изменение", "Удаление", "Просмотр", "Редактирование" и другие, в зависимости от вида объекта. Третьим параметром можно передать роль или пользователя ИБ — тогда проверяется не текущий сеанс, а именно они.

// есть ли право изменения у самой роли, без привязки к пользователю
ПравоДоступа("Изменение", Метаданные.Документы.РеализацияТоваровУслуг, Метаданные.Роли.ПолныеПрава);

Есть и вариант «проверить и остановиться»: ВыполнитьПроверкуПравДоступа("Изменение", Метаданные.Справочники.Номенклатура) вызывает исключение, если права нет. Удобно в начале серверной процедуры, которая не должна выполняться без прав.

Профиль безопасности — это не роль

Запрос «узнать роль через профиль безопасности» часто путают с правами пользователя. Профиль безопасности задаётся в кластере серверов 1С и ограничивает код: доступ к файловой системе, COM-объектам, внешним компонентам, интернет-ресурсам. К ролям пользователя он отношения не имеет.

Из кода можно узнать только, работает ли сейчас безопасный режим: функция БезопасныйРежим() возвращает Ложь, Истина или имя профиля безопасности строкой. Это полезно для расширений и внешних обработок, но на вопрос «какая роль у пользователя» не отвечает.

Какой способ выбрать: сравнение

СпособЧто даётКлиентВызов сервераУчитывает БСПКогда применять
РольДоступнаНаличие одной роли в сеансеДаНетНетВидимость элементов, простые условия
ПользовательИБ.РолиПолный список ролейНетДаНетОтладка, журналы, отчёты по правам
ПравоДоступаНаличие права на объектДаНетНетПроверка действия, а не названия роли
Пользователи.РолиДоступныХотя бы одна роль из спискаНет*Да*ДаТиповые конфигурации
Запрос к группам доступаГруппы, профили, роли по настройкамНетДаДаАудит, отчёты для администратора

* Модуль Пользователи серверный; на клиенте в БСП есть свой модуль ПользователиКлиент, состав его функций зависит от версии библиотеки.

Что именно нужно узнать в коде?

Особые случаи: пустой список пользователей, привилегированный режим, внешнее соединение

Проверка ролей ведёт себя неожиданно в нескольких ситуациях. Их стоит учесть заранее, иначе код «работает у разработчика и ломается у клиента».

  • 👤 Список пользователей пуст. Если в базе не создано ни одного пользователя, сеанс работает с полными правами. ТекущийПользователь() вернёт пользователя с пустым именем и пустой коллекцией Роли, а проверка по коллекции скажет, что ролей нет. Учебные и демонстрационные базы часто именно такие.
  • 🔓 Привилегированный режим. В нём проверка прав платформой не выполняется. Узнать режим можно функцией ПривилегированныйРежим(). У Пользователи.РолиДоступны в БСП для этого есть отдельный параметр, который определяет, считать ли привилегированный режим полными правами.
  • 🔌 Внешнее соединение и фоновые задания. Код выполняется от имени того пользователя, под которым установлено соединение или запущено задание. Регламентное задание без указанного пользователя работает с правами, отличными от интерактивного пользователя, — не завязывайте его логику на роли.
  • 🧩 Роль из расширения. Роли расширений доступны в Метаданные.Роли только когда расширение подключено. Если код основной конфигурации обращается к такой роли через точку, без подключённого расширения он не скомпилируется.

Защита от переименованных и отсутствующих ролей

Если имя роли приходит строкой — из настроек, параметров обработки, внешней обработки для разных конфигураций — сначала проверьте, что роль существует:

Функция РольЕстьИДоступна(ИмяРоли)

    ОбъектРоли = Метаданные.Роли.Найти(ИмяРоли);
    Если ОбъектРоли = Неопределено Тогда
        Возврат Ложь;
    КонецЕсли;

    Возврат РольДоступна(ОбъектРоли);

КонецФункции

Метаданные.Роли.Найти возвращает Неопределено, если роли с таким именем нет. Так внешняя обработка не упадёт на конфигурации, где роль называется иначе.

Проверка ролей на клиенте — это удобство интерфейса, а не защита. Скрытая кнопка не мешает вызвать серверный метод другим путём. Права на данные должны ограничиваться ролями и проверкой на сервере.

Готовые примеры кода на встроенном языке

Вывести роли текущего пользователя в сообщение

Пригодится при разборе обращения «у меня не открывается документ». Запустите во внешней обработке:

&НаСервере
Процедура ПоказатьРолиНаСервере()

    ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
    Если ПустаяСтрока(ПользовательИБ.Имя) Тогда
        Сообщить("Список пользователей пуст: сеанс работает с полными правами.");
        Возврат;
    КонецЕсли;

    Сообщить(СтрШаблон("Пользователь: %1, ролей: %2",
        ПользовательИБ.Имя, Формат(ПользовательИБ.Роли.Количество(), "ЧН=0; ЧГ=0")));

    Для Каждого Роль Из ПользовательИБ.Роли Цикл
        Сообщить(СтрШаблон("%1 (%2)", Роль.Имя, Роль.Синоним));
    КонецЦикла;

КонецПроцедуры

Проверить роли другого пользователя

Нужны права администратора: читать чужого пользователя ИБ может только тот, у кого есть право администрирования.

ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени("Иванова");
Если ПользовательИБ <> Неопределено Тогда
    ЕстьРоль = ПользовательИБ.Роли.Содержит(Метаданные.Роли.ПолныеПрава);
    МожноМенять = ПравоДоступа("Изменение",
        Метаданные.Справочники.Номенклатура, ПользовательИБ);
КонецЕсли;

Обратите внимание на разницу: Роли.Содержит отвечает про конкретную роль, ПравоДоступа с третьим параметром — про итоговое право по всем ролям пользователя.

Кэшировать результат на сеанс

Если проверка нужна в десятках мест, вынесите её в серверный общий модуль с повторным использованием возвращаемых значений «На время сеанса»:

// Общий модуль ПраваПользователяПовтИсп
// (Сервер, Вызов сервера, Повторное использование: На время сеанса)
Функция ЭтоМенеджерПродаж() Экспорт
    Возврат РольДоступна(Метаданные.Роли.МенеджерПродаж);
КонецФункции

На клиенте вызов ПраваПользователяПовтИсп.ЭтоМенеджерПродаж() уйдёт на сервер один раз, дальше значение берётся из кэша. Роль МенеджерПродаж здесь — пример, подставьте свою.

Если администратор поменял пользователю роли, кэш на время сеанса этого не увидит. Новые права пользователь получит после перезапуска 1С.

Частые ошибки при проверке ролей

  • ❌ Проверка по имени пользователя вместо роли. Условие Если ИмяПользователя() = "Администратор" ломается при первом же переименовании и не переносится между базами.
  • ❌ Сравнение роли со строкой синонима. Синоним «Полные права» зависит от языка интерфейса; сравнивайте объект метаданных или имя.
  • ❌ Вызов ПользователиИнформационнойБазы в клиентском коде. На тонком и веб-клиенте этого менеджера нет — нужна серверная функция.
  • ❌ Ручные галочки ролей в типовой конфигурации. В конфигурациях на БСП роли, проставленные в Конфигураторе мимо профилей, при следующей записи пользователя или обновлении прав могут быть перезаписаны по профилям групп доступа.
  • ❌ Защита данных только видимостью кнопок. Об этом выше: ограничения должны жить на сервере.

Частые вопросы

Можно ли узнать роль пользователя без программирования?
Да. В Конфигураторе откройте Администрирование → Пользователи, затем карточку пользователя и вкладку Прочие: там отмечены его роли. В типовых конфигурациях смотрите группы доступа пользователя в разделе Администрирование → Настройки пользователей и прав.
Почему РольДоступна возвращает Истина, хотя роли у пользователя нет?
Частые причины: в базе нет ни одного пользователя, код выполняется в привилегированном режиме или под другим пользователем (фоновое задание, внешнее соединение). Проверьте ИмяПользователя() и ПривилегированныйРежим() в той же точке кода.
Как получить синоним роли для вывода пользователю?
У объекта метаданных роли есть свойство Синоним: Метаданные.Роли.ПолныеПрава.Синоним. Имя (Имя) используйте в коде, синоним — в интерфейсе.
Работает ли РольДоступна в веб-клиенте и на мобильном клиенте?
В веб-клиенте — да, как и в тонком клиенте. Для мобильного приложения ориентируйтесь на синтакс-помощник своей версии платформы: там указан контекст доступности каждой функции.
Как проверить роль в запросе или в ограничении доступа RLS?
В тексте ограничения доступа на уровне записей есть функция РольДоступна(ИмяРоли). В обычном запросе её нет: проверку делайте в коде до выполнения запроса.