Переход инфраструктуры 1С на Linux и PostgreSQL — частая задача в рамках импортозамещения. Чтобы упростить этот процесс, можно использовать сценарий для автоматизации установки 1С и PostgreSQL Одна из проблем, с которой сталкиваются разработчики в новой среде, — интеграция с Active Directory (AD). В среде Windows для этого повсеместно использовался COM-объект, но в Linux он недоступен. Возникает вопрос: как теперь получить из AD дополнительные сведения о пользователях, такие как отдел, должность или организация?
Проанализируем ситуацию. Нам нужно из кода 1С, работающего на сервере под управлением Linux, отправить запрос в Active Directory и получить ответ. Ключевым протоколом для взаимодействия со службами каталогов, включая AD, является LDAP (Lightweight Directory Access Protocol). Рассмотрим два основных способа решения этой задачи.
Это самый прямой и быстрый способ, не требующий разработки дополнительных компонентов. Идея заключается в том, чтобы из 1С запустить стандартную для Linux консольную утилиту ldapsearch, передать ей все необходимые параметры для запроса, а затем получить и разобрать (распарсить) ее текстовый вывод. При этом важно помнить про обслуживание баз данных 1C на Postgresql, так как работа с внешними утилитами на сервере требует стабильной настройки всей системы.
Разберем по шагам, как это реализовать.
ldapsearch входит в пакет ldap-utils (Debian/Ubuntu) или openldap-clients (CentOS/RedHat). Как правило, системный администратор может легко ее установить.
-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);
Возврат ТД.ПолучитьТекст();
Исключение
Возврат "";
КонецПопытки;
КонецФункции
Преимущества подхода: простота реализации, отсутствие внешних зависимостей, кроме стандартных утилит ОС.
Недостатки: парсинг текста может быть ненадежным, если формат вывода изменится; передача пароля в командной строке небезопасна; создание нового процесса для каждого запроса создает дополнительную нагрузку.
Это более современный, гибкий и надежный подход. Идея заключается в создании небольшого веб-сервиса на любом удобном языке (Python, Go, Node.js), который будет служить "прокладкой" между 1С и Active Directory. Если ваша цель — обеспечить удобный доступ пользователям, также может быть полезен лаунчер для 1C с проверкой доменной авторизации.
Проанализируем архитектуру такого решения:
GET /user?login=ivanov.ii.Этот подход полностью скрывает сложность работы с 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 помогут избежать проблем с производительностью в будущем.