Как раздать роли пользователям через встроенный язык 1С

· 9 мин

Содержание

Роль пользователю в 1С 8.3 назначают через коллекцию Роли объекта ПользователиИнформационнойБазы: метод Роли.Добавить(Метаданные.Роли.ИмяРоли), а затем Записать(). Это базовый способ на встроенном языке — он работает и для одного пользователя, и для массовой обработки списка.

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

Два уровня хранения ролей: платформа и типовая логика

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

На уровне платформы роли привязаны к объекту ПользователиИнформационнойБазы (InfoBaseUser). У каждого пользователя ИБ есть коллекция Роли — именно её читает платформа при проверке прав. Это низкий уровень, доступный в любой конфигурации.

В типовых конфигурациях поверх этого работает подсистема «Управление доступом» из БСП. Пользователь хранится в справочнике Справочник.Пользователи, его права складываются из профилей групп доступа (Справочник.ПрофилиГруппДоступа), а сами роли платформы БСП пересчитывает автоматически. Если дописать роль напрямую в ПользователиИнформационнойБазы, БСП при следующей записи элемента справочника затрёт её обратно.

Правило простое: в вашей собственной или «тонкой» конфигурации без подсистемы доступа — работайте напрямую через ПользователиИнформационнойБазы. В типовой на БСП — через группы доступа (см. раздел про типовые ниже).

Чтобы не держать это в голове, вот сводка способов — какой когда применять:

СпособКогда применятьОграничение
ПользователиИнформационнойБазы.Ролисвоя или нетиповая конфигурация, разовая правкав типовой на БСП роль сбрасывается при записи
Массовая обработка в циклевыдать роль многим пользователям сразунужны права администратора ИБ, на больших базах долго
Группы доступа и профилитиповые: Бухгалтерия, ЗУП, УТроль задаётся не напрямую, а через профиль группы
COM-соединение или HTTP-сервисиз внешней программы, скрипта, интеграциитребует настройки соединения или публикации сервиса

Дальше — каждый способ с кодом и нюансами.

Назначение роли через объект ПользователиИнформационнойБазы

Это стандартный метод платформы. Находим пользователя по имени, добавляем роль, записываем:

Пользователь = ПользователиИнформационнойБазы.НайтиПоИмени("Иванов");

Если Пользователь <> Неопределено Тогда
    Пользователь.Роли.Добавить(Метаданные.Роли.МенеджерПоПродажам);
    Пользователь.Записать();
КонецЕсли;

Роли.Добавить() принимает объект метаданных роли — Метаданные.Роли.ИмяРоли, где имя совпадает с тем, как роль названа в дереве конфигурации. Передавать строку с именем нельзя, только ссылку на метаданные.

Полезные методы коллекции Роли:

  • 🔎 Содержит(Роль) — проверить, есть ли роль у пользователя (вернёт Истина/Ложь);
  • ➕ Добавить(Роль) — выдать роль;
  • ➖ Удалить(Роль) — отобрать одну роль;
  • 🧹 Очистить() — снять все роли сразу.

Перед выдачей лучше проверять, чтобы не плодить лишние записи:

Роль = Метаданные.Роли.МенеджерПоПродажам;

Если НЕ Пользователь.Роли.Содержит(Роль) Тогда
    Пользователь.Роли.Добавить(Роль);
    Пользователь.Записать();
КонецЕсли;

Если нужно заменить весь набор ролей, а не дополнить:

Пользователь.Роли.Очистить();
Пользователь.Роли.Добавить(Метаданные.Роли.БазовыеПрава);
Пользователь.Роли.Добавить(Метаданные.Роли.МенеджерПоПродажам);
Пользователь.Записать();

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

Массовое назначение ролей обработкой

Когда роль нужно выдать десяткам сотрудников, пишут внешнюю обработку . Принцип тот же, но пользователи перебираются в цикле. Чтобы не вызывать поиск по каждому имени, один раз получаем весь список:

Роль = Метаданные.Роли.ЧтениеОтчётов;

Для Каждого Пользователь Из ПользователиИнформационнойБазы.ПолучитьПользователей() Цикл

    Если Пользователь.Роли.Содержит(Роль) Тогда
        Продолжить;
    КонецЕсли;

    Пользователь.Роли.Добавить(Роль);
    Пользователь.Записать();

КонецЦикла;

ПолучитьПользователей() возвращает массив всех пользователей ИБ — его удобно отфильтровать по нужному признаку (например, только активным или только из определённого списка имён).

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

Частый сценарий — раздать роль по списку имён из таблицы значений или из файла. Тогда заранее собираем соответствие «имя → пользователь», чтобы не искать в цикле:

Соответствие = Новый Соответствие;
Для Каждого Пользователь Из ПользователиИнформационнойБазы.ПолучитьПользователей() Цикл
    Соответствие.Вставить(Пользователь.Имя, Пользователь);
КонецЦикла;

Для Каждого Имя Из СписокИмён Цикл
    Пользователь = Соответствие.Получить(Имя);
    Если Пользователь <> Неопределено Тогда
        Пользователь.Роли.Добавить(Метаданные.Роли.ЧтениеОтчётов);
        Пользователь.Записать();
    КонецЕсли;
КонецЦикла;

Так один проход по базе вместо сотни отдельных запросов НайтиПоИмени.

Роли в типовых конфигурациях: группы доступа вместо прямого кода

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

Правильный путь в типовой — через группы доступа. Через интерфейс это делается так: Администрирование → Настройки пользователей и прав → Группы доступа (точное название раздела зависит от конфигурации, но путь начинается с раздела Администрирование). Каждая группа доступа ссылается на профиль, а профиль содержит набор ролей. Пользователь получает роли через членство в группе.

Программно модель та же: нужно добавить пользователя в табличную часть Пользователи элемента справочника ГруппыДоступа (а не дописывать роль в объект ИБ). Логика примерно такая:

  1. Находим или создаём нужный профиль групп доступа с набором ролей.
  2. Находим группу доступа, привязанную к этому профилю.
  3. Добавляем ссылку на пользователя (Справочник.Пользователи) в табличную часть группы.
  4. Записываем элемент группы доступа.

В БСП есть служебные методы для записи пользователя ИБ и обновления его ролей из профилей. Если дорабатываете типовую — используйте штатный программный интерфейс подсистемы доступа, а не прямую правку Роли, иначе ваша доработка перестанет работать после обновления или первой же записи карточки пользователя.

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

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

Назначение ролей из внешней программы: COM-соединение

Когда роли нужно раздавать из внешней системы (скрипт развёртывания, кадровый портал, собственная утилита администратора), применяют внешнее соединение через COM-коннектор. Это и есть «сложный сценарий» для интеграций: код выполняется в контексте базы, но запускается снаружи.

Коннектор = Новый COMОбъект("V83.COMConnector");
Соединение = Коннектор.Connect(
    "Srvr=""server-1c"";Ref=""buh"";Usr=""Администратор"";Pwd=""пароль""");

Для Каждого Пользователь Из Соединение.ПользователиИнформационнойБазы.ПолучитьПользователей() Цикл
    // обработка на стороне базы
КонецЦикла;

Через объект Соединение доступен тот же контекст сервера, включая ПользователиИнформационнойБазы. Логику назначения лучше вынести в экспортную серверную процедуру конфигурации и вызывать её из внешнего соединения — так не придётся дублировать проверки прав и БСП-логику снаружи.

Два условия, без которых COM-соединение не поднимется: на машине, откуда идёт подключение, должна быть зарегистрирована компонента comcntr.dll (её ставит инсталлятор платформы), и разрядность вызывающей программы должна совпадать с разрядностью установленной 1С. Строка подключения для серверной базы начинается с Srvr и Ref, для файловой — с File.

Отдельно про REST. Штатный интерфейс OData (REST) отдаёт прикладные объекты — справочники, документы — но не управляет ролями пользователей ИБ напрямую: роли живут на уровне платформы, а не в составе данных OData. Чтобы назначать роли по HTTP из внешней системы, публикуют собственный HTTP-сервис, который внутри вызывает всё тот же ПользователиИнформационнойБазы. То есть REST здесь — это тонкая обёртка над встроенными методами, а не отдельный механизм.

Выдача роли при создании пользователя

Удобно назначать роли сразу в момент создания пользователя — чтобы не было «пустых» учёток без прав. При программном создании через СоздатьПользователя() роли добавляются до записи:

Новый = ПользователиИнформационнойБазы.СоздатьПользователя();
Новый.Имя = "Петров";
Новый.ПолноеИмя = "Петров Пётр";
Новый.АутентификацияСтандартная = Истина;
Новый.Роли.Добавить(Метаданные.Роли.БазовыеПрава);
Новый.Роли.Добавить(Метаданные.Роли.МенеджерПоПродажам);
Новый.Записать();

Обратите внимание на свойства пользователя при создании. Имя — это логин, по которому идёт вход и поиск НайтиПоИмени; ПолноеИмя — отображаемое имя в списке. Если вход выполняется под учётной записью Windows, вместо АутентификацияСтандартная задают АутентификацияОС и свойство ПользовательОС в формате домен\\учётка. Пароль для стандартной аутентификации устанавливают свойством Пароль до записи.

Если нужно, чтобы каждый новый сотрудник автоматически получал базовый набор, логику выдачи ролей размещают в обработчике, который отрабатывает при записи пользователя. В типовых конфигурациях для этого есть штатные механизмы профилей «по умолчанию» в подсистеме доступа — автозаполнение группы доступа при создании пользователя настраивается без кода, через карточку профиля, поэтому дублировать это собственным обработчиком в типовой не нужно.

Почему роль не назначается: разбор причин

Если код отработал без ошибок, а прав у пользователя не прибавилось — почти всегда дело в одной из причин ниже.

Диагностика: выберите симптом

Не пытайтесь «починить» типовую, очистив роли через Роли.Очистить() и выдав ПолныеПрава напрямую. В конфигурации на БСП это создаёт расхождение между платформенными ролями и группами доступа, и права начинают вести себя непредсказуемо. Работайте через штатную подсистему.

Производительность: массовые операции с пользователями

На базе с сотнями пользователей выдача ролей в лоб может идти долго. Несколько приёмов, которые реально ускоряют.

Не ищите пользователя в цикле. НайтиПоИмени внутри перебора — это повторные обращения к списку пользователей ИБ. Один раз постройте Соответствие имя → пользователь (пример выше) и берите из него.

Выполняйте массовую выдачу в фоновом задании. Долгую обработку запускайте через ФоновыеЗадания, чтобы не держать клиентский сеанс и не упираться в тайм-ауты. Пользователь при этом может продолжать работу.

Поднимайте привилегированный режим на сервере. Если логика гарантированно корректна и права проверены заранее, обёртка УстановитьПривилегированныйРежим(Истина) снимает лишние проверки доступа на каждой итерации:

УстановитьПривилегированныйРежим(Истина);
// массовая обработка пользователей
УстановитьПривилегированныйРежим(Ложь);

Привилегированный режим отключает контроль прав. Включайте его только в проверенном серверном коде и обязательно выключайте после блока. В клиентском коде он недоступен.

Не записывайте без необходимости. Проверяйте Роли.Содержит() перед Добавить() и вызывайте Записать() только если состав ролей реально изменился — лишние записи пользователя ИБ это самая дорогая часть операции.

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

Можно ли назначить роль по строковому имени, без Метаданные.Роли?
Напрямую — нет, Роли.Добавить() ждёт объект метаданных. Но можно получить его по имени через Метаданные.НайтиПоПолномуИмени("Роль.ИмяРоли") и передать результат в Добавить(). Так удобно, когда имя роли приходит параметром.
Как снять роль у всех пользователей сразу?
Переберите ПользователиИнформационнойБазы.ПолучитьПользователей(), для каждого вызовите Роли.Удалить(Метаданные.Роли.ИмяРоли) и Записать(). В типовой на БСП убирайте роль через профиль группы доступа, а не напрямую, иначе изменение не закрепится.
Нужны ли права администратора, чтобы выдавать роли кодом?
Да. Операции с ПользователиИнформационнойБазы требуют административных прав на информационную базу и выполняются на сервере. Из-под обычного пользователя без прав администрирования они завершатся ошибкой доступа.
Почему после обновления типовой мои программно выданные роли исчезли?
Скорее всего роли дописывались напрямую в пользователя ИБ в обход групп доступа. При обновлении и при записи карточки пользователя БСП пересчитывает роли из профилей и убирает «лишние». Переведите выдачу на группы доступа.
Как проверить, какие роли уже есть у пользователя?
Получите пользователя (НайтиПоИмени) и переберите коллекцию Роли или используйте Роли.Содержит(Метаданные.Роли.ИмяРоли) для конкретной роли. Для типовой полную картину прав лучше смотреть через отчёт по правам доступа в разделе администрирования.