Роли пользователя информационной базы из кода: Добавить, Записать и группы доступа БСП
Содержание
Чтобы программно добавить роль пользователю
в 1С 8.3, найдите пользователя информационной базы через ПользователиИнформационнойБазы.НайтиПоИмени(), вызовите ПользовательИБ.Роли.Добавить(Метаданные.Роли.ИмяРоли) и сохраните изменения методом ПользовательИБ.Записать(). Код выполняется на сервере, под пользователем с правом «Администрирование» или в привилегированном режиме.
Это рабочий путь для самописных конфигураций. В типовых решениях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) роль, добавленная напрямую, проживёт недолго: подсистема управления доступом пересчитает роли по профилям групп доступа и уберёт «лишнюю». Там правильный ход — включить пользователя в группу доступа. Оба варианта разобраны ниже с готовым кодом.
Как устроены права в 1С: роли, пользователи ИБ и профили
Права в 1С:Предприятии 8.3 держатся на трёх уровнях. Если перепутать уровни, код «работает», но права не появляются.
- 🧩 Роль — объект метаданных конфигурации (ветка
Общие → Ролив конфигураторе). В ней описано, что разрешено: чтение справочника, проведение документа, запуск обработки. Роль нельзя создать из кода во время работы программы — только в конфигураторе или в расширении. - 👤 Пользователь информационной базы — запись в служебном списке пользователей базы. У него есть имя, способ аутентификации и коллекция ролей. Именно её и меняет код.
- 📁 Элемент справочника «Пользователи» — прикладной объект типовых конфигураций. Он связан с пользователем ИБ через реквизит
ИдентификаторПользователяИБ. Сам по себе прав не даёт.
В типовых конфигурациях добавляется четвёртый уровень — профили и группы доступа. Профиль — это набор ролей, группа доступа — профиль плюс список участников и ограничения (например, по организациям). Роли пользователя ИБ подсистема собирает автоматически: объединяет роли всех профилей, в группы которых он входит.
| Где назначать роль | Когда подходит | Что будет при пересчёте прав |
|---|---|---|
Напрямую в ПользовательИБ.Роли | Своя конфигурация без БСП, служебные пользователи интеграций | Ничего, роль остаётся |
| Через группу доступа (БСП) | БП 3.0, ЗУП 3.1, УТ 11, ERP, КА | Роль сохраняется, потому что её даёт профиль |
| Напрямую в типовой конфигурации | Нигде, кроме короткой отладки | Роль будет снята при обновлении ролей пользователей |
Где взять пользователя: поиск по имени, ссылке и идентификатору
Первый шаг любого кода — получить объект ПользовательИнформационнойБазы. Менеджер ПользователиИнформационнойБазы доступен на сервере, в толстом клиенте и во внешнем соединении. В тонком клиенте и веб-клиенте его нет, поэтому код выносят в серверную процедуру или общий серверный модуль.
По имени для входа
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени("Иванов");
Если ПользовательИБ = Неопределено Тогда
ВызватьИсключение "Пользователь ИБ с именем Иванов не найден";
КонецЕсли;
Ищется именно имя для входа (свойство Имя), а не полное имя. Если в окне входа человек выбирает «Иванов И.И.», а в списке пользователей имя записано как ivanov, искать нужно по ivanov.
По ссылке на элемент справочника «Пользователи»
В типовых конфигурациях чаще есть ссылка на элемент справочника, а не имя. Переход к пользователю ИБ идёт через уникальный идентификатор:
Идентификатор = ПользовательСсылка.ИдентификаторПользователяИБ;
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору(Идентификатор);
Если метод вернул Неопределено, у элемента справочника нет связанной учётной записи: человек заведён в справочнике, но вход в программу ему не разрешён.
Текущий пользователь и полный список
ПользователиИнформационнойБазы.ТекущийПользователь()— тот, под кем идёт сеанс. Если в базе нет ни одного пользователя, вернётся пустой пользователь без имени.ПользователиИнформационнойБазы.ПолучитьПользователей()— массив всех пользователей базы, удобно для массовых операций.
Добавление роли пользователю программно: Добавить() и Записать()
Свойство Роли пользователя ИБ — это коллекция ролей. У неё четыре метода, которые нужны на практике:
| Метод | Что делает |
|---|---|
Добавить(Роль) | Добавляет роль в коллекцию |
Удалить(Роль) | Убирает роль |
Содержит(Роль) | Возвращает Истина, если роль уже есть |
Очистить() | Удаляет все роли |
Параметр — объект метаданных роли, а не строка с именем. Получают его так: Метаданные.Роли.БазовыеПрава или Метаданные.Роли.Найти("БазовыеПрава").
Ключевой момент: изменения коллекции ролей хранятся только в памяти, пока не вызван Записать(). Забыть запись — самая частая причина вопроса «код отработал без ошибок, а роли нет».
Минимальный рабочий пример для серверного общего модуля:
Процедура ДобавитьРольПользователю(ИмяПользователя, ИмяРоли) Экспорт
Роль = Метаданные.Роли.Найти(ИмяРоли);
Если Роль = Неопределено Тогда
ВызватьИсключение СтрШаблон("Роль %1 не найдена в конфигурации", ИмяРоли);
КонецЕсли;
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователя);
Если ПользовательИБ = Неопределено Тогда
ВызватьИсключение СтрШаблон("Пользователь %1 не найден", ИмяПользователя);
КонецЕсли;
Если ПользовательИБ.Роли.Содержит(Роль) Тогда
Возврат; // роль уже назначена, лишняя запись не нужна
КонецЕсли;
ПользовательИБ.Роли.Добавить(Роль);
ПользовательИБ.Записать();
КонецПроцедуры
Проверка Содержит() не обязательна для корректности, но экономит лишнюю запись и не засоряет журнал регистрации событиями изменения пользователя.
Новая роль начинает действовать со следующего сеанса. Если пользователь сейчас в программе, ему нужно перезапустить 1С. Функция РольДоступна() в его текущем сеансе продолжит возвращать старый результат.
Создание нового пользователя сразу с ролью
Если учётной записи ещё нет, её создают методом СоздатьПользователя() и заполняют до первой записи:
НовыйПользователь = ПользователиИнформационнойБазы.СоздатьПользователя();
НовыйПользователь.Имя = "integration";
НовыйПользователь.ПолноеИмя = "Служебный пользователь обмена";
НовыйПользователь.АутентификацияСтандартная = Истина;
НовыйПользователь.Пароль = ПарольИзНастроек; // не храните пароль в тексте модуля
НовыйПользователь.ПоказыватьВСпискеВыбора = Ложь;
НовыйПользователь.Роли.Добавить(Метаданные.Роли.Найти("ПолныеПрава"));
НовыйПользователь.Записать();
Имя роли полных прав в разных конфигурациях может отличаться, поэтому выше роль ищется через Найти(), а не обращением через точку: обращение к несуществующей роли через точку упадёт с ошибкой.
Роли из конфигурации, расширения и профили БСП
Под «предопределёнными» ролями обычно понимают те, что заложены в конфигурацию разработчиком. Под «динамическими» — роли, которые назначаются по условию во время работы: по должности, подразделению, факту прохождения проверки. Платформа не делит роли на такие виды, разница только в том, откуда берётся роль и кто решает, кому её дать.
Роли из расширения конфигурации
В расширение можно добавить собственную роль, не снимая типовую конфигурацию
с поддержки. После подключения расширения такая роль появляется в Метаданные.Роли и назначается тем же Роли.Добавить(). Если расширение отключить, роль пропадёт у всех пользователей, поэтому код назначения стоит защищать проверкой Метаданные.Роли.Найти().
Назначение роли по условию
Типичный сценарий: роль «Согласование заявок» нужна всем, кто записан руководителем подразделения. Задачу решает регламентное задание или обработчик записи справочника, который сравнивает текущий набор ролей с нужным и вызывает Добавить() или Удалить(). Важно, чтобы этот код не боролся с другим механизмом назначения ролей, иначе роли будут «мигать» после каждого прохода.
Типовые конфигурации: группы доступа вместо прямой записи
В БП 3.0, ЗУП 3.1 и УТ 11 вручную права назначают в разделе Администрирование → Настройки пользователей и прав, через группы доступа. Программный аналог — добавить пользователя
в табличную часть «Пользователи» элемента справочника ГруппыДоступа:
Процедура ВключитьВГруппуДоступа(ПользовательСсылка, ИмяГруппы) Экспорт
ГруппаСсылка = Справочники.ГруппыДоступа.НайтиПоНаименованию(ИмяГруппы, Истина);
Если ГруппаСсылка.Пустая() Тогда
ВызватьИсключение СтрШаблон("Группа доступа %1 не найдена", ИмяГруппы);
КонецЕсли;
ГруппаОбъект = ГруппаСсылка.ПолучитьОбъект();
ГруппаОбъект.Заблокировать();
Если ГруппаОбъект.Пользователи.Найти(ПользовательСсылка, "Пользователь") = Неопределено Тогда
ГруппаОбъект.Пользователи.Добавить().Пользователь = ПользовательСсылка;
ГруппаОбъект.Записать();
КонецЕсли;
КонецПроцедуры
При записи группы подсистема управления доступом сама пересчитает роли участников по профилю. В новых версиях БСП в общем модуле УправлениеДоступом есть экспортные процедуры для включения пользователя в группу или профиль. Откройте модуль в конфигураторе и найдите их поиском по слову «Профиль»: вызов программного интерфейса БСП надёжнее прямой работы с табличной частью, он переживёт обновления.
Если нужной роли нет ни в одном профиле, создайте свой профиль в пользовательском режиме и включите в него роль. Прямое добавление роли в типовой конфигурации будет отменено при следующем обновлении ролей пользователей.
Права на запуск кода, ошибки и безопасность
Менять пользователей ИБ может только тот, у кого есть право «Администрирование». У обычного пользователя код упадёт с ошибкой нарушения прав доступа. Варианты решения:
- Запускать операцию под администратором (регламентное задание от имени служебного пользователя, обработка администратора).
- Включить привилегированный режим на сервере перед работой с пользователями:
УстановитьПривилегированныйРежим(Истина);
Попытка
ДобавитьРольПользователю(ИмяПользователя, ИмяРоли);
Исключение
Инфо = ИнформацияОбОшибке();
ЗаписьЖурналаРегистрации("Назначение ролей", УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеПредставлениеОшибки(Инфо));
УстановитьПривилегированныйРежим(Ложь);
ВызватьИсключение КраткоеПредставлениеОшибки(Инфо);
КонецПопытки;
УстановитьПривилегированныйРежим(Ложь);
Привилегированный режим отключает проверку прав для всего кода в этом блоке. Не включайте его в процедуре, которую можно вызвать с клиента с произвольным именем роли: пользователь сможет выдать себе полные права. Список допустимых ролей держите на сервере и сверяйте с ним входной параметр.
Ещё несколько правил безопасности:
- 🔒 Не выдавайте роль полных прав из кода без явной причины и записи в журнал регистрации.
- 🧾 Пишите в журнал, кто, кому и какую роль назначил. Платформа фиксирует изменение пользователя, но не причину.
- 👥 Не оставляйте базу без администратора: если код снимает роли (например, через
Очистить()), проверьте, что хотя бы у одного пользователя остаётся право «Администрирование». - 🧪 Отлаживайте на копии базы. Ошибка в массовом цикле меняет права сразу у всех.
Примеры кода для частых задач с ролями пользователей
Массово добавить роль всем пользователям
Полезно, когда в конфигурацию добавили новую роль, нужную всем (например, роль доступа к новому отчёту):
Роль = Метаданные.Роли.Найти("ИспользованиеНовогоОтчета");
Если Роль = Неопределено Тогда
ВызватьИсключение "Роль не найдена";
КонецЕсли;
Изменено = 0;
Для Каждого ПользовательИБ Из ПользователиИнформационнойБазы.ПолучитьПользователей() Цикл
Если Не ПользовательИБ.Роли.Содержит(Роль) Тогда
ПользовательИБ.Роли.Добавить(Роль);
ПользовательИБ.Записать();
Изменено = Изменено + 1;
КонецЕсли;
КонецЦикла;
Сообщить(СтрШаблон("Роль добавлена пользователям: %1", Формат(Изменено, "ЧН=0; ЧГ=0")));
Если пользователей 40, а роль уже была у 12, сообщение покажет 28.
Скопировать роли одного пользователя другому
Образец = ПользователиИнформационнойБазы.НайтиПоИмени("Петрова");
Получатель = ПользователиИнформационнойБазы.НайтиПоИмени("Сидоров");
Для Каждого Роль Из Образец.Роли Цикл
Если Не Получатель.Роли.Содержит(Роль) Тогда
Получатель.Роли.Добавить(Роль);
КонецЕсли;
КонецЦикла;
Получатель.Записать();
Здесь запись идёт один раз после цикла: все роли добавляются в памяти, а сохраняются одним вызовом.
Добавить роль через внешнее соединение
Из другой программы или другой базы можно подключиться через COM-соединение (V83.COMConnector) и вызвать тот же код. Объекты базы доступны через объект соединения:
Коннектор = Новый COMОбъект("V83.COMConnector");
Соединение = Коннектор.Connect("Srvr=""server1c"";Ref=""buh"";Usr=""admin"";Pwd=""..."";");
ПользовательИБ = Соединение.ПользователиИнформационнойБазы.НайтиПоИмени("Иванов");
ПользовательИБ.Роли.Добавить(Соединение.Метаданные.Роли.Найти("БазовыеПрава"));
ПользовательИБ.Записать();
Пользователь в строке подключения должен иметь право «Администрирование», а разрядность зарегистрированного COM-компонента — совпадать с разрядностью вызывающей программы.
Проверить, какие роли есть у пользователя
Для Каждого Роль Из ПользовательИБ.Роли Цикл
Сообщить(Роль.Имя + " — " + Роль.Синоним);
КонецЦикла;
Этот список удобно вывести до и после изменения, чтобы убедиться, что код сделал ровно то, что задумано.