При переносе кодовой базы из тонкого или толстого клиента 1С в веб-интерфейс разработчики часто сталкиваются с неприятной ошибкой: «Невозможно создание объекта сервером программирования объектов» (в англоязычной локализации — «Automation server can't create object»). Данная ошибка возникает при попытке инициализировать COM-соединение или ActiveX-объект непосредственно в коде управляемой формы, которая исполняется в браузере. Типичным примером является попытка получить имя текущего пользователя операционной системы через скрипт wscript.network.
В рамках этой статьи мы подробно разберем, почему возникает эта ошибка, проанализируем архитектурные ограничения веб-клиента 1С и рассмотрим несколько надежных, безопасных способов реализации сквозной авторизации (SSO) без использования уязвимых COM-технологий на стороне клиента.
Для начала проанализируем ситуацию с технической точки зрения. В тонком клиенте 1С код выполняется в контексте операционной системы Windows, где среда выполнения имеет прямой доступ к системным библиотекам и интерфейсам программирования приложений (API). Строка кода:
NetWork = Новый COMОбъект("wscript.network");
отрабатывает успешно, так как операционная система без проблем создает экземпляр системного COM-компонента и возвращает его платформе 1С.
Однако в веб-клиенте вся логика клиентских модулей транслируется платформой 1С:Предприятие в код на языке JavaScript, который выполняется внутри изолированной среды (песочницы) веб-браузера (Chrome, Edge, Firefox, Safari). Из соображений безопасности современные браузеры жестко блокируют любой прямой доступ к ресурсам операционной системы компьютера пользователя. Браузер не может и не должен запускать произвольные COM-объекты или ActiveX-компоненты. Если бы это было возможно, любой вредоносный сайт в интернете мог бы получить полный контроль над компьютером посетителя.
Никакой «волшебной настройки» в современных браузерах для обхода этого ограничения безопасности не существует. Использование устаревшего браузера Internet Explorer с заниженными настройками безопасности зон («Надежные узлы») в современных реалиях неприемлемо, так как этот браузер официально снят с поддержки и заблокирован во многих корпоративных сетях.
Следовательно, нам необходимо полностью отказаться от идеи получения имени пользователя операционной системы силами клиентского JavaScript-кода в браузере. Вместо этого мы должны перенести задачу идентификации пользователя на уровень веб-сервера и платформы 1С.
Если все 20 тысяч сотрудников работают в корпоративном домене Active Directory, наиболее правильным и стандартным решением является использование встроенной доменной авторизации 1С:Предприятия через веб-сервер (например, Microsoft IIS). В этом случае пользователю вообще не потребуется вводить логин и пароль: веб-сервер сам договорится с браузером, получит доменный токен и передаст его платформе 1С.
Разберем по шагам, как настроить эту связку на веб-сервере IIS:
Теперь нам необходимо настроить конфигурационный файл публикации 1С. Этот файл называется default.vrd и находится в физическом каталоге публикации на веб-сервере. Откроем его текстовым редактором и убедимся, что в параметрах соединения включено использование операционной системы для авторизации:
<?xml version="1.0" encoding="UTF-8"?>
<point xmlns="http://v8.1c.ru/8.2/virtual-resource-system"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
base="/MyBase"
ib="Srvr="1C-Server";Ref="MyBase";">
<ws>
<point name="WebServices" alias="ws.1cws"/>
</ws>
<httpServices/>
<useOSAuthenticationValue>true</useOSAuthenticationValue>
</point>
Обратим внимание на тег useOSAuthenticationValue. Установив его значение в true, мы указываем платформе, что при подключении через веб-клиент необходимо автоматически использовать учетные данные операционной системы, переданные веб-сервером.
Как упомянул автор темы на форуме, в его инфраструктуре веб-сервер IIS и сервер приложений 1С находятся на разных физических серверах. Это классический сценарий, при котором стандартная Windows-аутентификация по протоколу NTLM перестает работать. Возникает проблема так называемого «двойного перехода» (Double-Hop).
Выясним причину этой проблемы. Когда браузер пользователя обращается к IIS, он передает свои учетные данные. IIS успешно авторизует пользователя локально. Но когда IIS пытается обратиться к серверу приложений 1С от имени этого пользователя, он не может этого сделать, так как протокол NTLM запрещает повторную передачу (делегирование) учетных данных на третий сервер. В результате сервер 1С отвергает запрос, считая его анонимным.
Чтобы решить проблему двойного перехода, нам потребуется настроить протокол аутентификации Kerberos и активировать ограниченное делегирование (Kerberos Constrained Delegation — KCD) в домене Active Directory. Рассмотрим схему настройки:
setspn -S HTTP/web-iis.domain.local domain\iis_service_account
setspn -S MSSQLSvc/1c-server.domain.local:1541 domain\usr1cv8
iis_service_account), перейдем в ее свойства на вкладку «Делегирование» (Delegation). Выберем вариант «Доверять этому пользователю делегирование только определенным службам» (Trust this user for delegation to specified services only) и укажем службу сервера 1С (зарегистрированный ранее SPN для usr1cv8).После успешной настройки Kerberos веб-сервер IIS сможет бесшовно передавать доменное имя пользователя на сервер 1С, и сквозной вход в базу через веб-клиент заработает без ошибок.
Автор темы выражает серьезное беспокойство: «как авторизовать того, кого еще нет в пользователях 1С? Ведь новые люди заходят постоянно, у нас 20 тысяч сотрудников». Действительно, если доменный пользователь попытается зайти в 1С через веб-клиент, а в списке пользователей информационной базы 1С для него нет сопоставленной карточки с заполненным полем «Пользователь ОС», платформа выдаст ошибку доступа.
Чтобы решить эту проблему элегантно и без участия администратора, мы должны настроить фоновую синхронизацию пользователей 1С с каталогом Active Directory (LDAP) на стороне сервера. Напишем регламентное задание, которое будет запускаться каждые 10 минут, опрашивать домен на предмет новых сотрудников и автоматически создавать для них учетные записи в базе 1С с необходимыми правами.
Рассмотрим пример кода на стороне сервера 1С, который подключается к домену по протоколу LDAP и синхронизирует учетные записи:
Процедура СинхронизироватьПользователейСActiveDirectory() Экспорт
// Настройки подключения к Active Directory
Домен = "domain.local";
LDAPПуть = "LDAP://OU=Employees,DC=domain,DC=local";
// Подключаемся к AD через COM-объект ADODB на сервере 1С
// Обратите внимание: на сервере 1С (под управлением Windows) COM-объекты работают отлично!
Connection = Новый COMОбъект("ADODB.Connection");
Command = Новый COMОбъект("ADODB.Command");
Connection.Provider = "ADsDSOObject";
Попытка
Connection.Open("Active Directory Provider");
Исключение
ЗаписьЖурналаРегистрации("Синхронизация AD", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка подключения к AD: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Command.ActiveConnection = Connection;
// Формируем запрос на получение пользователей домена (выбираем имя, логин и статус блокировки)
ЗапросLDAP = "SELECT sAMAccountName, displayName, userAccountControl FROM '" + LDAPПуть + "' WHERE objectCategory='user'";
Command.CommandText = ЗапросLDAP;
Command.Properties("Page Size").Value = 1000; // Для обработки больших списков
Попытка
RecordSet = Command.Execute();
Исключение
ЗаписьЖурналаРегистрации("Синхронизация AD", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка выполнения запроса LDAP: " + ОписаниеОшибки());
Connection.Close();
Возврат;
КонецПопытки;
// Обходим выборку доменных пользователей
Пока НЕ RecordSet.EOF Цикл
ЛогинДомена = Строка(RecordSet.Fields("sAMAccountName").Value);
ПолноеИмя = Строка(RecordSet.Fields("displayName").Value);
ФлагиУчетки = Число(RecordSet.Fields("userAccountControl").Value);
// Проверяем, активна ли учетная запись (флаг 2 означает отключенную учетную запись)
АктивенВAD = (BitwiseAnd(ФлагиУчетки, 2) = 0);
Если АктивенВAD И ЗначениеЗаполнено(ЛогинДомена) Тогда
ИмяПользователяОС = "\\" + Домен + "\" + ЛогинДомена;
// Ищем, есть ли уже такой пользователь в базе 1С
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ЛогинДомена);
Если ПользовательИБ = Неопределено Тогда
// Создаем нового пользователя информационной базы
НовыйПользователь = ПользователиИнформационнойБазы.СоздатьПользователя();
НовыйПользователь.Имя = ЛогинДомена;
НовыйПользователь.ПолноеИмя = ПолноеИмя;
НовыйПользователь.АутентификацияОС = Истина;
НовыйПользователь.ПользовательОС = ИмяПользователяОС;
// Назначаем базовую роль для входа в систему
БазоваяРоль = Метаданные.Роли.ЗапускВебКлиента;
НовыйПользователь.Роли.Добавить(БазоваяРоль);
Попытка
НовыйПользователь.Записать();
ЗаписьЖурналаРегистрации("Синхронизация AD", УровеньЖурналаРегистрации.Информация, , ,
"Создан новый пользователь: " + ЛогинДомена);
Исключение
ЗаписьЖурналаРегистрации("Синхронизация AD", УровеньЖурналаРегистрации.Предупреждение, , ,
"Не удалось записать пользователя " + ЛогинДомена + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЕсли;
RecordSet.MoveNext();
КонецЦикла;
RecordSet.Close();
Connection.Close();
КонецПроцедуры
// Вспомогательная функция для побитовой операции И
Функция BitwiseAnd(Значение1, Значение2)
Результат = 0;
Множитель = 1;
Пока Значение1 > 0 И Значение2 > 0 Цикл
Остаток1 = Значение1 % 2;
Остаток2 = Значение2 % 2;
Если Остаток1 = 1 И Остаток2 = 1 Тогда
Результат = Результат + Множитель;
КонецЕсли;
Значение1 = Цел(Значение1 / 2);
Значение2 = Цел(Значение2 / 2);
Множитель = Множитель * 2;
КонецЦикла;
Возврат Результат;
EndFunction
Благодаря этому фоновому механизму, новые сотрудники, заведенные системными администраторами в Active Directory, автоматически попадут в справочник пользователей 1С в течение 10 минут. Когда они впервые перейдут по веб-ссылке, система распознает их доменные имена и впустит в веб-клиент без единого лишнего клика.
Если корпоративная инфраструктура включает не только Windows-ноутбуки, но и мобильные устройства (смартфоны, планшеты на iOS и Android), стандартная Windows-аутентификация Kerberos может вызвать серьезные трудности в настройке. В таких случаях рекомендуется использовать современный индустриальный стандарт сквозной аутентификации — OpenID Connect, встроенная поддержка которого появилась в платформе 1С:Предприятие.
Проанализируем схему работы OpenID Connect:
Для настройки интеграции 1С с OpenID Connect достаточно прописать параметры провайдера в файле default.vrd в специальной секции:
<openidConnect>
<issuer uri="https://keycloak.domain.com/auth/realms/corp"/>
<clientId>1c-web-client</clientId>
<clientSecret>super-secure-client-secret-key</clientSecret>
<claimName>preferred_username</claimName>
</openidConnect>
Преимуществом этого подхода является кроссплатформенность: авторизация будет безотказно работать во всех браузерах на операционных системах Windows, macOS, Linux, Android и iOS, полностью исключая необходимость в использовании COM-объектов, небезопасных плагинов или сложных схем проброса учетных данных через IIS.
Мы подробно разобрали причины возникновения ошибки «Невозможно создание объекта сервером программирования объектов» и изучили четыре надежных сценария построения сквозной аутентификации в веб-клиенте 1С. Выбор конкретного архитектурного решения зависит от требований безопасности вашей компании и используемых операционных систем на рабочих станциях пользователей.