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