Проверка ролей текущего пользователя в 1С 8.3: функции платформы, БСП и запросы
Содержание
Быстрее всего узнать роль текущего пользователя в 1С функцией глобального контекста РольДоступна(Метаданные.Роли.ИмяРоли): она возвращает Истина, если у сеанса есть эта роль. Работает и на клиенте, и на сервере, вызова сервера не требует. Полный список ролей даёт серверный код: ПользователиИнформационнойБазы.ТекущийПользователь().Роли.
Всё остальное — уточнения под задачу. В типовых конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) роли раздаются через профили групп доступа, и там удобнее функции общего модуля Пользователи. А если вопрос не «есть ли роль», а «можно ли читать этот справочник», правильнее проверять право, а не роль.
Ниже код для платформы 8.3 с управляемым интерфейсом. Всё, что относится к платформе, работает в любой конфигурации; всё, что относится к БСП, — только там, где подключена Библиотека стандартных подсистем.
Роль текущего пользователя через глобальный контекст
Платформа даёт два основных инструмента. Они отвечают на разные вопросы.
| Инструмент | Что возвращает | Где доступен |
|---|---|---|
РольДоступна(Роль) | Булево: есть ли одна конкретная роль | Клиент и сервер |
ПользователиИнформационнойБазы.ТекущийПользователь().Роли | Коллекция всех ролей пользователя | Сервер, толстый клиент, внешнее соединение |
ИмяПользователя(), ПолноеИмяПользователя() | Имя пользователя ИБ, строка | Клиент и сервер |
Функция РольДоступна
Параметр — объект метаданных роли или строка с именем роли. Через метаданные надёжнее: опечатку в имени поймает синтаксический контроль, а строку — нет.
Если РольДоступна(Метаданные.Роли.ПолныеПрава) Тогда
Элементы.ГруппаАдминистрирование.Видимость = Истина;
КонецЕсли;
Типичное место для такой проверки — ПриСозданииНаСервере формы: скрыть кнопку, сделать поле только для просмотра, поменять отбор списка.
На клиенте РольДоступна вызывается без обращения к серверу. Поэтому её можно смело использовать в обработчиках команд формы, не боясь лишних серверных вызовов.
Коллекция ролей пользователя ИБ
Когда нужен весь набор ролей — например, вывести его в отладочное сообщение или записать в журнал — используйте менеджер пользователей информационной базы. Он есть только на сервере, поэтому в форме понадобится серверная процедура.
&НаСервереБезКонтекста
Функция РолиТекущегоПользователя()
Результат = Новый Массив;
ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
Для Каждого Роль Из ПользовательИБ.Роли Цикл
Результат.Добавить(Роль.Имя);
КонецЦикла;
Возврат Результат;
КонецФункции
Проверить одну роль в этой коллекции можно методом Содержит:
ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
ЕстьПолныеПрава = ПользовательИБ.Роли.Содержит(Метаданные.Роли.ПолныеПрава);
Разница принципиальная: коллекция Роли показывает, что записано в настройках пользователя, а РольДоступна — что реально доступно в текущем сеансе. В обычных условиях ответы совпадают. Расхождения появляются в особых случаях, о них ниже.
Сведения о ролях в типовых конфигурациях на БСП
В Бухгалтерии, ЗУП, УТ и других конфигурациях на БСП администратор не ставит галочки ролей вручную. Он включает пользователя в группу доступа, а у группы есть профиль со списком ролей. Платформенные роли пользователю ИБ проставляет сама БСП.
Посмотреть это в интерфейсе можно в разделе Администрирование → Настройки пользователей и прав: там списки пользователей, групп доступа и профилей групп доступа. В карточке пользователя есть переход к его правам доступа.
Функции общего модуля Пользователи
В коде БСП удобнее, чем голая платформа: функции учитывают полноправного пользователя и привилегированный режим.
| Функция | Что делает |
|---|---|
Пользователи.ТекущийПользователь() | Ссылка на элемент справочника Пользователи |
Пользователи.АвторизованныйПользователь() | Пользователь или внешний пользователь текущего сеанса |
Пользователи.ЭтоПолноправныйПользователь() | Истина для администратора с полными правами |
Пользователи.РолиДоступны("Роль1, Роль2") | Истина, если доступна хотя бы одна из ролей |
Пример проверки на сервере:
Если Пользователи.РолиДоступны("ДобавлениеИзменениеДанныхБухгалтерии, ПолныеПрава") Тогда
// разрешаем редактирование
КонецЕсли;
Имена ролей здесь условные — подставьте роли своей конфигурации. Посмотреть их можно в Конфигураторе, ветка Общие → Роли.
Запрос к группам доступа
Иногда нужна не платформенная роль, а то, как права выданы на уровне прикладных данных: в каких группах доступа состоит пользователь и какие роли входят в их профили. Это запрос к справочникам БСП.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ГруппыДоступаПользователи.Ссылка КАК ГруппаДоступа,
| ГруппыДоступаПользователи.Ссылка.Профиль КАК Профиль,
| ПрофилиРоли.Роль КАК Роль
|ИЗ
| Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПрофилиГруппДоступа.Роли КАК ПрофилиРоли
| ПО ГруппыДоступаПользователи.Ссылка.Профиль = ПрофилиРоли.Ссылка
|ГДЕ
| ГруппыДоступаПользователи.Пользователь = &Пользователь
| И НЕ ГруппыДоступаПользователи.Ссылка.ПометкаУдаления";
Запрос.УстановитьПараметр("Пользователь", Пользователи.ТекущийПользователь());
Выборка = Запрос.Выполнить().Выбрать();
Поле Роль в профиле — ссылка на справочник идентификаторов объектов метаданных, а не сам объект метаданных.
Запрос ловит только прямое членство. Если в группу доступа включена группа пользователей, а не сам пользователь, он в выборку не попадёт. Структура справочников БСП меняется между редакциями библиотеки: перед использованием сверьте имена таблиц и реквизитов в своём Конфигураторе.
Для проверки «может ли человек что-то сделать прямо сейчас» этот запрос не подходит. Он отражает настройки, а не состояние сеанса. Для решения в коде используйте РольДоступна или функции модуля Пользователи.
Право доступа вместо роли и профили безопасности
Проверка конкретной роли хрупкая. Разработчик завтра разделит роль на две — и все условия РольДоступна(Метаданные.Роли.Старая) перестанут работать. Если важно действие, а не название роли, проверяйте право.
Функция ПравоДоступа
Если ПравоДоступа("Изменение", Метаданные.Справочники.Номенклатура) Тогда
// пользователь может менять номенклатуру
КонецЕсли;
Первый параметр — имя права строкой: "Чтение", "Добавление", "Изменение", "Удаление", "Просмотр", "Редактирование" и другие, в зависимости от вида объекта. Третьим параметром можно передать роль или пользователя ИБ — тогда проверяется не текущий сеанс, а именно они.
// есть ли право изменения у самой роли, без привязки к пользователю
ПравоДоступа("Изменение", Метаданные.Документы.РеализацияТоваровУслуг, Метаданные.Роли.ПолныеПрава);
Есть и вариант «проверить и остановиться»: ВыполнитьПроверкуПравДоступа("Изменение", Метаданные.Справочники.Номенклатура) вызывает исключение, если права нет. Удобно в начале серверной процедуры, которая не должна выполняться без прав.
Профиль безопасности — это не роль
Запрос «узнать роль через профиль безопасности» часто путают с правами пользователя. Профиль безопасности задаётся в кластере серверов 1С и ограничивает код: доступ к файловой системе, COM-объектам, внешним компонентам, интернет-ресурсам. К ролям пользователя он отношения не имеет.
Из кода можно узнать только, работает ли сейчас безопасный режим: функция БезопасныйРежим() возвращает Ложь, Истина или имя профиля безопасности строкой. Это полезно для расширений и внешних обработок, но на вопрос «какая роль у пользователя» не отвечает.
Какой способ выбрать: сравнение
| Способ | Что даёт | Клиент | Вызов сервера | Учитывает БСП | Когда применять |
|---|---|---|---|---|---|
РольДоступна | Наличие одной роли в сеансе | Да | Нет | Нет | Видимость элементов, простые условия |
ПользовательИБ.Роли | Полный список ролей | Нет | Да | Нет | Отладка, журналы, отчёты по правам |
ПравоДоступа | Наличие права на объект | Да | Нет | Нет | Проверка действия, а не названия роли |
Пользователи.РолиДоступны | Хотя бы одна роль из списка | Нет* | Да* | Да | Типовые конфигурации |
| Запрос к группам доступа | Группы, профили, роли по настройкам | Нет | Да | Да | Аудит, отчёты для администратора |
* Модуль Пользователи серверный; на клиенте в БСП есть свой модуль ПользователиКлиент, состав его функций зависит от версии библиотеки.
РольДоступна(Метаданные.Роли.ИмяРоли) прямо в форме, на клиенте или в ПриСозданииНаСервере.ПравоДоступа("Изменение", Метаданные.…): не зависит от того, как роли названы и разделены.ПользователиИнформационнойБазы.ТекущийПользователь().Роли.Пользователи.РолиДоступны("Роль1, Роль2") или Пользователи.ЭтоПолноправныйПользователь().ГруппыДоступа и ПрофилиГруппДоступа.Особые случаи: пустой список пользователей, привилегированный режим, внешнее соединение
Проверка ролей ведёт себя неожиданно в нескольких ситуациях. Их стоит учесть заранее, иначе код «работает у разработчика и ломается у клиента».
- 👤 Список пользователей пуст. Если в базе не создано ни одного пользователя, сеанс работает с полными правами.
ТекущийПользователь()вернёт пользователя с пустым именем и пустой коллекциейРоли, а проверка по коллекции скажет, что ролей нет. Учебные и демонстрационные базы часто именно такие. - 🔓 Привилегированный режим. В нём проверка прав платформой не выполняется. Узнать режим можно функцией
ПривилегированныйРежим(). УПользователи.РолиДоступныв БСП для этого есть отдельный параметр, который определяет, считать ли привилегированный режим полными правами. - 🔌 Внешнее соединение и фоновые задания. Код выполняется от имени того пользователя, под которым установлено соединение или запущено задание. Регламентное задание без указанного пользователя работает с правами, отличными от интерактивного пользователя, — не завязывайте его логику на роли.
- 🧩 Роль из расширения. Роли расширений доступны в
Метаданные.Ролитолько когда расширение подключено. Если код основной конфигурации обращается к такой роли через точку, без подключённого расширения он не скомпилируется.
Защита от переименованных и отсутствующих ролей
Если имя роли приходит строкой — из настроек, параметров обработки, внешней обработки для разных конфигураций — сначала проверьте, что роль существует:
Функция РольЕстьИДоступна(ИмяРоли)
ОбъектРоли = Метаданные.Роли.Найти(ИмяРоли);
Если ОбъектРоли = Неопределено Тогда
Возврат Ложь;
КонецЕсли;
Возврат РольДоступна(ОбъектРоли);
КонецФункции
Метаданные.Роли.Найти возвращает Неопределено, если роли с таким именем нет. Так внешняя обработка не упадёт на конфигурации, где роль называется иначе.
Проверка ролей на клиенте — это удобство интерфейса, а не защита. Скрытая кнопка не мешает вызвать серверный метод другим путём. Права на данные должны ограничиваться ролями и проверкой на сервере.
Готовые примеры кода на встроенном языке
Вывести роли текущего пользователя в сообщение
Пригодится при разборе обращения «у меня не открывается документ». Запустите во внешней обработке:
&НаСервере
Процедура ПоказатьРолиНаСервере()
ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
Если ПустаяСтрока(ПользовательИБ.Имя) Тогда
Сообщить("Список пользователей пуст: сеанс работает с полными правами.");
Возврат;
КонецЕсли;
Сообщить(СтрШаблон("Пользователь: %1, ролей: %2",
ПользовательИБ.Имя, Формат(ПользовательИБ.Роли.Количество(), "ЧН=0; ЧГ=0")));
Для Каждого Роль Из ПользовательИБ.Роли Цикл
Сообщить(СтрШаблон("%1 (%2)", Роль.Имя, Роль.Синоним));
КонецЦикла;
КонецПроцедуры
Проверить роли другого пользователя
Нужны права администратора: читать чужого пользователя ИБ может только тот, у кого есть право администрирования.
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени("Иванова");
Если ПользовательИБ <> Неопределено Тогда
ЕстьРоль = ПользовательИБ.Роли.Содержит(Метаданные.Роли.ПолныеПрава);
МожноМенять = ПравоДоступа("Изменение",
Метаданные.Справочники.Номенклатура, ПользовательИБ);
КонецЕсли;
Обратите внимание на разницу: Роли.Содержит отвечает про конкретную роль, ПравоДоступа с третьим параметром — про итоговое право по всем ролям пользователя.
Кэшировать результат на сеанс
Если проверка нужна в десятках мест, вынесите её в серверный общий модуль с повторным использованием возвращаемых значений «На время сеанса»:
// Общий модуль ПраваПользователяПовтИсп
// (Сервер, Вызов сервера, Повторное использование: На время сеанса)
Функция ЭтоМенеджерПродаж() Экспорт
Возврат РольДоступна(Метаданные.Роли.МенеджерПродаж);
КонецФункции
На клиенте вызов ПраваПользователяПовтИсп.ЭтоМенеджерПродаж() уйдёт на сервер один раз, дальше значение берётся из кэша. Роль МенеджерПродаж здесь — пример, подставьте свою.
Если администратор поменял пользователю роли, кэш на время сеанса этого не увидит. Новые права пользователь получит после перезапуска 1С.
Частые ошибки при проверке ролей
- ❌ Проверка по имени пользователя вместо роли. Условие
Если ИмяПользователя() = "Администратор"ломается при первом же переименовании и не переносится между базами. - ❌ Сравнение роли со строкой синонима. Синоним «Полные права» зависит от языка интерфейса; сравнивайте объект метаданных или имя.
- ❌ Вызов
ПользователиИнформационнойБазыв клиентском коде. На тонком и веб-клиенте этого менеджера нет — нужна серверная функция. - ❌ Ручные галочки ролей в типовой конфигурации. В конфигурациях на БСП роли, проставленные в Конфигураторе мимо профилей, при следующей записи пользователя или обновлении прав могут быть перезаписаны по профилям групп доступа.
- ❌ Защита данных только видимостью кнопок. Об этом выше: ограничения должны жить на сервере.
Частые вопросы
Можно ли узнать роль пользователя без программирования?
Администрирование → Пользователи, затем карточку пользователя и вкладку Прочие: там отмечены его роли. В типовых конфигурациях смотрите группы доступа пользователя в разделе Администрирование → Настройки пользователей и прав.Почему РольДоступна возвращает Истина, хотя роли у пользователя нет?
ИмяПользователя() и ПривилегированныйРежим() в той же точке кода.Как получить синоним роли для вывода пользователю?
Синоним: Метаданные.Роли.ПолныеПрава.Синоним. Имя (Имя) используйте в коде, синоним — в интерфейсе.Работает ли РольДоступна в веб-клиенте и на мобильном клиенте?
Как проверить роль в запросе или в ограничении доступа RLS?
РольДоступна(ИмяРоли). В обычном запросе её нет: проверку делайте в коде до выполнения запроса.