Как в 1С на Linux получить данные пользователя из Active Directory?

Программист IT и автоматизация бизнеса
← На главную

Переход инфраструктуры 1С на Linux и PostgreSQL — частая задача в рамках импортозамещения. Чтобы упростить этот процесс, можно использовать сценарий для автоматизации установки 1С и PostgreSQL Одна из проблем, с которой сталкиваются разработчики в новой среде, — интеграция с Active Directory (AD). В среде Windows для этого повсеместно использовался COM-объект, но в Linux он недоступен. Возникает вопрос: как теперь получить из AD дополнительные сведения о пользователях, такие как отдел, должность или организация?

Проанализируем ситуацию. Нам нужно из кода 1С, работающего на сервере под управлением Linux, отправить запрос в Active Directory и получить ответ. Ключевым протоколом для взаимодействия со службами каталогов, включая AD, является LDAP (Lightweight Directory Access Protocol). Рассмотрим два основных способа решения этой задачи.

Решение 1: Вызов консольной утилиты ldapsearch

Это самый прямой и быстрый способ, не требующий разработки дополнительных компонентов. Идея заключается в том, чтобы из 1С запустить стандартную для Linux консольную утилиту ldapsearch, передать ей все необходимые параметры для запроса, а затем получить и разобрать (распарсить) ее текстовый вывод. При этом важно помнить про обслуживание баз данных 1C на Postgresql, так как работа с внешними утилитами на сервере требует стабильной настройки всей системы.

Разберем по шагам, как это реализовать.

  1. Убедитесь, что утилита установлена. Утилита ldapsearch входит в пакет ldap-utils (Debian/Ubuntu) или openldap-clients (CentOS/RedHat). Как правило, системный администратор может легко ее установить.
  2. Сформируйте командную строку. В коде 1С необходимо собрать строку для вызова утилиты. Рассмотрим основные параметры:
    • -H: Адрес LDAP-сервера (контроллера домена). Пример: ldap://dc.mydomain.local.
    • -D: Имя пользователя (Bind DN) для подключения к AD. Обычно это специальная учетная запись с правами на чтение каталога. Пример: "CN=1c_user,CN=Users,DC=mydomain,DC=local".
    • -w: Пароль для этого пользователя. Важно: учитывая, почему хранить пароли и ключи в коде — плохо, используйте защищенное хранилище или параметры сеанса.
    • -b: База поиска (Base DN), то есть точка в иерархии каталога, с которой начинается поиск. Пример: "DC=mydomain,DC=local".
    • Фильтр поиска: Условие для отбора объектов. Чтобы найти конкретного пользователя по логину, можно использовать фильтр "(sAMAccountName=ivanov.ii)".
    • Атрибуты: Список полей, которые нужно получить. Например, department (отдел), title (должность), company (организация), displayName (отображаемое имя).

Посмотрим на пример команды, которая ищет пользователя с логином ivanov.ii и запрашивает его отдел и должность:


ldapsearch -H ldap://dc.mydomain.local -D "user@domain.com" -w "password" -b "dc=domain,dc=com" "(sAMAccountName=ivanov.ii)" department title

Далее рассмотрим, как это реализовать в коде 1С.

Для выполнения внешней команды используется метод ЗапуститьПриложение(). Он может сразу вернуть результат выполнения в виде строк, если правильно настроить перенаправление вывода.

Пример кода 1С для вызова ldapsearch и парсинга результата:


&НаСервереБезКонтекста
Функция ПолучитьДанныеПользователяAD(Логин)

    ИмяВыходногоФайла = ПолучитьИмяВременногоФайла("txt");
    ИмяФайлаОшибок = ПолучитьИмяВременногоФайла("txt");

    // Параметры подключения к Active Directory
    // ВАЖНО: Используйте механизмы, позволяющие безопасно хранить параметры
    СерверAD = "ldap://dc.mydomain.local";
    ПользовательAD = "CN=1c_user,CN=Users,DC=mydomain,DC=local";
    ПарольAD = "SuperSecretPassword";
    БазаПоиска = "DC=mydomain,DC=local";

    // Атрибуты, которые мы хотим получить
    Атрибуты = "department title company";

    // Формируем фильтр поиска по логину
    Фильтр = "(sAMAccountName=" + Логин + ")";

    // Собираем командную строку. Обратите внимание на экранирование кавычек.
    КоманднаяСтрока = "ldapsearch -H " + СерверAD
        + " -D """ + ПользовательAD + """"
        + " -w """ + ПарольAD + """"
        + " -b """ + БазаПоиска + """"
        + " """ + Фильтр + """"
        + " " + Атрибуты;
    
    КодВозврата = 0;
    // Запускаем приложение и перенаправляем вывод в файлы
    ЗапуститьПриложение(КоманднаяСтрока, ИмяВыходногоФайла, Истина, КодВозврата);
    
    Если КодВозврата <> 0 Тогда
        // Обработка ошибки выполнения команды
        ТекстОшибки = ПрочитатьТекстовыйФайл(ИмяФайлаОшибок);
        ВызватьИсключение("Ошибка выполнения ldapsearch: " + ТекстОшибки);
        Возврат Неопределено;
    КонецЕсли;

    // Читаем результат из временного файла
    ТекстовыйДокумент = Новый ТекстовыйДокумент;
    ТекстовыйДокумент.Прочитать(ИмяВыходногоФайла);

    УдалитьФайлы(ИмяВыходногоФайла, ИмяФайлаОшибок);
    
    // Парсим результат
    Результат = Новый Структура("Отдел, Должность, Организация");
    Для Сч = 1 По ТекстовыйДокумент.КоличествоСтрок() Цикл
        Строка = ТекстовыйДокумент.ПолучитьСтроку(Сч);
        
        // Результат ldapsearch обычно имеет формат "атрибут: значение"
        ПозицияРазделителя = СтрНайти(Строка, ":");
        Если ПозицияРазделителя > 0 Тогда
            Ключ = СокрЛП(Лев(Строка, ПозицияРазделителя - 1));
            Значение = СокрЛП(Сред(Строка, ПозицияРазделителя + 1));
            
            Если Ключ = "department" Тогда
                Результат.Отдел = Значение;
            ИначеЕсли Ключ = "title" Тогда
                Результат.Должность = Значение;
            ИначеЕсли Ключ = "company" Тогда
                Результат.Организация = Значение;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;

    Возврат Результат;

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

&НаСервере
Функция ПрочитатьТекстовыйФайл(ПутьКФайлу)
    Попытка
        ТД = Новый ТекстовыйДокумент;
        ТД.Прочитать(ПутьКФайлу, КодировкаТекста.UTF8);
        Возврат ТД.ПолучитьТекст();
    Исключение
        Возврат "";
    КонецПопытки;
КонецФункции

Преимущества подхода: простота реализации, отсутствие внешних зависимостей, кроме стандартных утилит ОС.

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

Решение 2: Создание промежуточного веб-сервиса (микросервиса)

Это более современный, гибкий и надежный подход. Идея заключается в создании небольшого веб-сервиса на любом удобном языке (Python, Go, Node.js), который будет служить "прокладкой" между 1С и Active Directory. Если ваша цель — обеспечить удобный доступ пользователям, также может быть полезен лаунчер для 1C с проверкой доменной авторизации.

Проанализируем архитектуру такого решения:

  1. 1С (Клиент): Отправляет простой HTTP-запрос на адрес микросервиса. Например, GET /user?login=ivanov.ii.
  2. Микросервис (Посредник): Принимает HTTP-запрос. С помощью специализированной библиотеки для работы с LDAP подключается к Active Directory. Выполняет тот же LDAP-запрос, что и в первом решении.
  3. Active Directory (Источник данных): Отдает данные микросервису в структурированном виде.
  4. Микросервис: Форматирует полученные данные в удобный для 1С формат (например, JSON) и отправляет их в теле HTTP-ответа.
  5. 1С: Получает HTTP-ответ, читает тело ответа (строку JSON) и десериализует его во внутренние структуры данных 1С.

Этот подход полностью скрывает сложность работы с LDAP от 1С. Для программиста 1С задача сводится к отправке HTTP-запроса и обработке JSON.

Пример кода 1С для обращения к такому веб-сервису:


&НаСервере
Функция ПолучитьДанныеПользователяЧерезСервис(Логин)

    // Адрес нашего микросервиса
    АдресСервиса = "http://localhost:8080";
    Ресурс = "/user?login=" + Логин;
    
    Попытка
        // Настраиваем соединение. Если сервис требует SSL, используем ЗащищенноеСоединениеOpenSSL
        Соединение = Новый HTTPСоединение(АдресСервиса);
        
        // Создаем GET-запрос
        Запрос = Новый HTTPЗапрос(Ресурс);
        
        // Отправляем запрос и получаем ответ
        Ответ = Соединение.Получить(Запрос);
        
        Если Ответ.КодСостояния = 200 Тогда
            // Если все успешно, читаем тело ответа (JSON)
            ТелоОтветаJSON = Ответ.ПолучитьТелоКакСтроку();
            
            // Десериализуем JSON в структуры 1С
            ЧтениеJSON = Новый ЧтениеJSON;
            ЧтениеJSON.УстановитьСтроку(ТелоОтветаJSON);
            
            ДанныеПользователя = ПрочитатьJSON(ЧтениеJSON); // Встроенная функция 1С
            
            // Предполагаем, что сервис вернул объект с полями department, title, company
            Результат = Новый Структура;
            Результат.Вставить("Отдел", ДанныеПользователя.department);
            Результат.Вставить("Должность", ДанныеПользователя.title);
            Результат.Вставить("Организация", ДанныеПользователя.company);

            Возврат Результат;
            
        Иначе
            // Обработка кодов ошибок (404 - не найден, 500 - ошибка сервера и т.д.)
            ЗаписьЖурналаРегистрации("Ошибка.ADИнтеграция", УровеньЖурналаРегистрации.Ошибка, , , 
                "Сервис вернул ошибку: " + Ответ.КодСостояния + " " + Ответ.ПолучитьТелоКакСтроку());
            Возврат Неопределено;
        КонецЕсли;
        
    Исключение
        ЗаписьЖурналаРегистрации("Ошибка.ADИнтеграция", УровеньЖурналаРегистрации.Ошибка, , , 
            "Не удалось подключиться к сервису интеграции с AD: " + ОписаниеОшибки());
        Возврат Неопределено;
    КонецПопытки;

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

Преимущества подхода:

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

Вывод

Переход на Linux не закрывает возможности интеграции 1С с Active Directory. Вместо проприетарных COM-объектов мы начинаем использовать стандартные и открытые протоколы.

Для простых и редких запросов вполне подойдет метод с вызовом утилиты ldapsearch. Он быстр в реализации и не требует дополнительных компонентов.

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

← На главную