Пользователь информационной базы из кода: встроенный язык, COM и БСП

· 9 мин

Содержание

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

Это голая платформенная часть. В типовых конфигурациях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11, ERP) так делать нельзя: пользователь ИБ появится, но в справочнике «Пользователи» его не будет, а роли перезапишет подсистема управления доступом. Для типовых баз нужен свой способ, он разобран ниже отдельно.

Где можно создать пользователя из кода и где нельзя

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

КонтекстДоступен ли менеджерКомментарий
Сервер (&НаСервере, общий модуль с флагом «Сервер»)✅ даОсновной вариант
Тонкий клиент, веб-клиент❌ нетНужен серверный вызов
Толстый клиент (обычное приложение)✅ даУстаревший сценарий
Внешнее соединение (COM)✅ даДля скриптов и интеграций
OData, стандартный REST-интерфейс❌ нетПользователей ИБ через OData не создать
Свой HTTP-сервис✅ через серверный модульНужна своя авторизация и проверки

Ещё два ограничения, о которые спотыкаются чаще всего:

  • 🔐 Права. Без права «Администрирование» у текущего пользователя запись падает с ошибкой нарушения прав. Выход — УстановитьПривилегированныйРежим(Истина) в серверном коде. Так делает и сама БСП.
  • 👤 Первый пользователь. Если список пользователей пуст, первым должен быть записан пользователь с административными правами. Иначе платформа откажет в записи: без администратора базой некому было бы управлять.

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

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

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

Функция СоздатьПользователяИБ(Имя, ПолноеИмя, Пароль, ИменаРолей) Экспорт

    Имя = СокрЛП(Имя);
    Если ПустаяСтрока(Имя) Тогда
        ВызватьИсключение "Не указано имя пользователя";
    КонецЕсли;

    УстановитьПривилегированныйРежим(Истина);

    Если ПользователиИнформационнойБазы.НайтиПоИмени(Имя) <> Неопределено Тогда
        УстановитьПривилегированныйРежим(Ложь);
        ВызватьИсключение СтрШаблон("Пользователь %1 уже существует", Имя);
    КонецЕсли;

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

    Для Каждого ИмяРоли Из ИменаРолей Цикл
        Роль = Метаданные.Роли.Найти(ИмяРоли);
        Если Роль = Неопределено Тогда
            УстановитьПривилегированныйРежим(Ложь);
            ВызватьИсключение СтрШаблон("Роль %1 не найдена в конфигурации", ИмяРоли);
        КонецЕсли;
        НовыйПользователь.Роли.Добавить(Роль);
    КонецЦикла;

    НовыйПользователь.Записать();
    УстановитьПривилегированныйРежим(Ложь);

    Возврат НовыйПользователь.УникальныйИдентификатор;

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

Пояснения к свойствам:

  • Имя — логин, под которым входят в программу. Уникален в пределах базы.
  • ПолноеИмя — то, что видно в списке выбора при входе и в журнале регистрации.
  • Пароль — задаётся открытым текстом, в базе хранится хеш. Прочитать пароль обратно нельзя: свойство при чтении пустое.
  • Язык — если в конфигурации один язык, строку можно не писать. Имя языка Русский проверьте в дереве метаданных своей конфигурации.
  • РежимЗапуска — значение Авто отдаёт выбор клиента платформе.

Вызов с клиента оформляйте через серверную процедуру формы: &НаСервереБезКонтекста Процедура СоздатьНаСервере(...), которая обращается к функции общего модуля. Передавайте пароль параметром, а не храните его в реквизите формы.

Как изменить или удалить уже созданного пользователя

Тот же объект находится по имени или по идентификатору:

Пользователь = ПользователиИнформационнойБазы.НайтиПоИмени("Иванов");
Если Пользователь <> Неопределено Тогда
    Пользователь.Пароль = НовыйПароль;
    Пользователь.Записать();
КонецЕсли;

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

Создание пользователя через внешнее COM-соединение

Внешнее соединение нужно, когда пользователей заводит внешний скрипт: портал самообслуживания, сценарий онбординга, массовое создание из таблицы. Работает только в Windows.

Подготовка

  1. Зарегистрируйте COM-компоненту той же версии, что и платформа базы. Команда в консоли администратора: regsvr32 "C:\Program Files\1cv8\8.3.xx.xxxx\bin\comcntr.dll"
  2. Разрядность скрипта и компоненты должна совпадать. 64-разрядный Python не увидит 32-разрядную comcntr.dll.
  3. Заведите в базе служебного пользователя с правом «Администрирование» и правом внешнего соединения. Под ним и будет подключаться скрипт.

Пример на VBScript

Set Connector = CreateObject("V83.COMConnector")
Set Base = Connector.Connect("Srvr=""srv1c"";Ref=""buh"";Usr=""ServiceAdmin"";Pwd=""секрет"";")

Set Users = Base.ПользователиИнформационнойБазы
If Users.НайтиПоИмени("Петрова") Is Nothing Then
    Set U = Users.СоздатьПользователя()
    U.Имя = "Петрова"
    U.ПолноеИмя = "Петрова Анна"
    U.АутентификацияСтандартная = True
    U.Пароль = "Временный123"
    U.Роли.Добавить Base.Метаданные.Роли.Найти("ПолныеПрава")
    U.Записать
End If

Для файловой базы вместо Srvr и Ref пишут File=""D:\Bases\Buh"";.

Пример на Python (pywin32)

import win32com.client

connector = win32com.client.Dispatch("V83.COMConnector")
base = connector.Connect('Srvr="srv1c";Ref="buh";Usr="ServiceAdmin";Pwd="секрет";')

users = base.ПользователиИнформационнойБазы
if users.НайтиПоИмени("Сидоров") is None:
    user = users.СоздатьПользователя()
    user.Имя = "Сидоров"
    user.ПолноеИмя = "Сидоров Пётр"
    user.АутентификацияСтандартная = True
    user.Пароль = "Временный123"
    user.Записать()

Через COM доступны и общие модули конфигурации с флагом «Внешнее соединение». Надёжнее написать функцию из предыдущего раздела в таком модуле и вызывать её одной строкой: base.ОбщийМодуль.СоздатьПользователяИБ(...). Тогда вся логика и проверки живут в базе, а скрипт только передаёт параметры.

Не храните пароль служебного пользователя в тексте скрипта. Берите его из переменной окружения или хранилища секретов. Строку соединения с паролем не пишите в логи.

Альтернатива COM — запуск клиента в пакетном режиме с внешней обработкой: 1cv8.exe ENTERPRISE /S "srv1c\buh" /N ServiceAdmin /P секрет /Execute "D:\create_user.epf". В модуле формы обработки при открытии вызывается серверная процедура создания. Способ медленнее COM, зато не требует регистрации компоненты.

Типовые конфигурации на БСП: справочник «Пользователи»

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

  • 📇 элемент справочника Пользователи — на него ссылаются документы, ответственные, настройки;
  • 🔑 пользователь ИБ — учётная запись платформы с логином и паролем.

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

УстановитьПривилегированныйРежим(Истина);

НовыйПользователь = Справочники.Пользователи.СоздатьЭлемент();
НовыйПользователь.Наименование = "Кузнецова Ольга";

ОписаниеПользователяИБ = Пользователи.НовоеОписаниеПользователяИБ();
ОписаниеПользователяИБ.Вставить("Действие", "Записать");
ОписаниеПользователяИБ.Имя = "Кузнецова";
ОписаниеПользователяИБ.ВходВПрограммуРазрешен = Истина;
ОписаниеПользователяИБ.АутентификацияСтандартная = Истина;
ОписаниеПользователяИБ.Пароль = "Временный123";

НовыйПользователь.ДополнительныеСвойства.Вставить("ОписаниеПользователяИБ", ОписаниеПользователяИБ);
НовыйПользователь.Записать();

УстановитьПривилегированныйРежим(Ложь);

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

Тот же код удобно положить во внешнюю обработку. Расширение или доработка типовой конфигурации для разового заведения сотрудников не нужны.

Роли, профили и группы доступа

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

В конфигурациях с подсистемой «Управление доступом» роли напрямую не назначают. Набор ролей задаёт профиль групп доступа, пользователь получает его через группу доступа. Роли, добавленные кодом мимо групп, слетят при следующем обновлении прав. Включение в группу выглядит так:

ГруппаОбъект = Справочники.ГруппыДоступа.НайтиПоНаименованию("Бухгалтеры").ПолучитьОбъект();
СтрокаПользователя = ГруппаОбъект.Пользователи.Добавить();
СтрокаПользователя.Пользователь = НовыйПользователь.Ссылка;
ГруппаОбъект.Записать();

Администратора добавляют в предопределённую группу Справочники.ГруппыДоступа.Администраторы.

ЗадачаГолая платформаКонфигурация на БСП
Дать набор правРоли.Добавить()Добавить в группу доступа
Сделать администраторомРоль с правом «Администрирование»Группа «Администраторы»
Ограничить по организациямТолько своими RLS-шаблонамиНастройки групп доступа
Где видно результатКонфигуратор, список пользователейАдминистрирование → Настройки пользователей и прав

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

Проверки и обработка ошибок при записи

Метод Записать() вызывает исключение при любой проблеме. Без обработки скрипт упадёт посреди пакета, и половина пользователей окажется заведённой, половина нет. Оборачивайте запись и логируйте причину:

Попытка
    НовыйПользователь.Записать();
Исключение
    Текст = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
    ЗаписьЖурналаРегистрации("СозданиеПользователей",
        УровеньЖурналаРегистрации.Ошибка, , Имя, Текст);
    ВызватьИсключение;
КонецПопытки;

Что проверять до записи, чтобы не ловить исключения:

  • ✏️ Имя не пустое и без пробелов по краям. СокрЛП() спасает от двух «одинаковых» логинов.
  • 🔁 Имя свободно. НайтиПоИмени() возвращает Неопределено, если логин не занят. Сравнение имён не учитывает регистр.
  • 🧩 Роли существуют. Метаданные.Роли.Найти() вернёт Неопределено для опечатки, а не ошибку.
  • 🔒 Пароль проходит политику. Если в параметрах информационной базы включены минимальная длина и проверка сложности, простой пароль не запишется.
  • 🪪 Доменный пользователь не занят. Один и тот же ПользовательОС нельзя назначить двум пользователям ИБ.
Диагностика: выберите симптом

Синхронизация с Active Directory и другими системами

Ручное заведение логинов перестаёт работать, когда сотрудников сотни. Три типовых сценария:

Вход по доменной учётке

Пользователю включают аутентификацию операционной системы и указывают доменное имя:

НовыйПользователь.АутентификацияОС = Истина;
НовыйПользователь.ПользовательОС = "\\CORP\a.petrova";
НовыйПользователь.АутентификацияСтандартная = Ложь;

Формат строки — два обратных слеша, домен, слеш, логин. Список сотрудников берут из выгрузки AD (например, PowerShell-скриптом в CSV), а 1С по расписанию сверяет его со своим списком: новых заводит, уволенным снимает флаг входа. Удалять уволенных не стоит: в БСП на элемент справочника ссылаются документы.

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

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

Новый.СохраняемоеЗначениеПароля = Исходный.СохраняемоеЗначениеПароля;

Так пользователь входит в новую базу со старым паролем, и администратору не нужно рассылать временные.

HTTP-сервис для кадровой системы или портала

Внешняя система вызывает HTTP-сервис 1С с JSON (имя, ФИО, группа доступа), сервис вызывает ту же функцию общего модуля. Здесь обязательно:

  1. Отдельный служебный пользователь публикации с минимальными правами на сам сервис.
  2. Проверка, что переданная группа доступа есть в белом списке. Иначе портал сможет выдать кому-то права администратора.
  3. Возврат внешней системе уникального идентификатора пользователя ИБ: по нему она потом будет менять и блокировать запись, а не по логину, который могут переименовать.
Можно ли создать пользователя 1С без входа в Конфигуратор?
Да. Достаточно внешней обработки, запущенной в режиме «Предприятие» под пользователем с правом «Администрирование», или COM-соединения из скрипта.
Как заставить пользователя сменить временный пароль при первом входе?
В конфигурациях на БСП в описании пользователя ИБ есть признак обязательной смены пароля при входе. В голой конфигурации такую проверку пишут сами в обработчике начала работы системы.
Почему созданный кодом пользователь не виден в списке при входе?
Свойство ПоказыватьВСпискеВыбора равно Ложь. Пользователь всё равно может войти, введя логин вручную.
Можно ли создать пользователя из веб-клиента?
Да, если код создания выполняется на сервере. С клиента вызывается серверная процедура, сам менеджер пользователей на клиенте недоступен.
Чем опасно назначать роли кодом в типовой конфигурации?
Подсистема управления доступом пересчитывает роли по группам доступа. Роль, добавленная напрямую, пропадёт после ближайшего обновления прав или изменения профиля.