При интеграции 1С со сторонними корпоративными системами нередко возникает задача обращения к веб-сервису, настроенному на сквозную доменную аутентификацию Windows (Active Directory, Kerberos/NTLM). При этом требуется, чтобы сторонний сервис авторизовал именно того сотрудника, который в данный момент работает в сеансе 1С, но без явного ввода его сетевого пароля. Рассмотрим подробнее, с какими архитектурными ограничениями платформы 1С здесь приходится сталкиваться, и разберем по шагам рабочие варианты решения этой задачи.
В конструкторе объекта WSПрокси и в методе WSСсылки.СоздатьWSПрокси() разработчикам доступен параметр ИспользоватьАутентификациюОС. Казалось бы, достаточно установить этот флаг в значение Истина, оставить имя пользователя и пароль пустыми, и веб-сервис будет успешно вызван. Однако на практике разработчик сталкивается с неочевидной ошибкой: Ошибка HTTP (чаще всего 401 Unauthorized).
Выясним причину такого поведения системы:
&НаСервере исполняются в контексте рабочего процесса сервера приложений (rphost). Когда на сервере выполняется обращение к внешнему ресурсу с флагом ИспользоватьАутентификациюОС = Истина, операционная система задействует учетную запись, под которой запущена сама служба сервера 1С. Если служба 1С работает под локальной учетной записью (например, usr1cv8), у нее попросту нет прав в домене Active Directory для авторизации на внешнем сервисе.WSОпределения и WSПрокси в управляемом приложении не могут быть созданы на стороне тонкого клиента. Они доступны исключительно на сервере, в толстом клиенте или во внешнем соединении. Поэтому вызвать WSПрокси непосредственно на рабочем месте пользователя в режиме тонкого клиента невозможно.Разберем наиболее надежный и универсальный обходной путь, который позволяет выполнить запрос от имени залогиненного пользователя Windows без ввода пароля в режиме тонкого клиента. В отличие от WSПрокси, объект HTTPСоединение доступен в контексте &НаКлиенте и полностью поддерживает аутентификацию операционной системы.
Архитектура этого решения строится следующим образом:
HTTPСоединение, у которого параметр ИспользоватьАутентификациюОС равен Истина, а логин и пароль не заполняются.Посмотрим на пример клиентской процедуры отправки SOAP-запроса:
&НаКлиенте
Процедура ВызватьСервисОтИмениПользователя()
Сервер = "service.domain.local";
Порт = 80; // Или 443 для HTTPS
ОтносительныйАдрес = "/Services/DataExchange.asmx";
// Параметры конструктора HTTPСоединение:
// Сервер, Порт, Пользователь, Пароль, Прокси, Таймаут, ЗащищенноеСоединение, ИспользоватьАутентификациюОС
Соединение = Новый HTTPСоединение(Сервер, Порт, "", "", , 30, , Истина);
// Формируем тело SOAP-конверта вручную
ТелоSOAP =
"<?xml version=""1.0"" encoding=""utf-8""?>
|<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance""
| xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
| xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
| <soap:Body>
| <LoadData xmlns=""http://tempuri.org/"">
| <ParamName>ПримерЗначения</ParamName>
| </LoadData>
| </soap:Body>
|</soap:Envelope>";
Запрос = Новый HTTPЗапрос(ОтносительныйАдрес);
Запрос.Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
Запрос.Заголовки.Вставить("SOAPAction", "http://tempuri.org/LoadData");
Запрос.УстановитьТелоИзСтроки(ТелоSOAP, КодировкаТекста.UTF8);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния = 200 Тогда
СтрокаОтветаXML = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
ОбработатьРезультатНаСервере(СтрокаОтветаXML);
Иначе
Сообщить(СтрШаблон("Ошибка вызова сервиса. Код состояния: %1", Ответ.КодСостояния));
КонецЕсли;
Исключение
ИнформацияОбОшибке = ОписаниеОшибки();
Сообщить("Сбой при выполнении сетевого запроса: " + ИнформацияОбОшибке);
КонецПопытки;
КонецПроцедуры
Рассмотрим, как обработать полученный ответ на сервере с помощью объекта ЧтениеXML:
&НаСервереБезКонтекста
Процедура ОбработатьРезультатНаСервере(Знач СтрокаОтветаXML)
Чтение = Новый ЧтениеXML;
Чтение.УстановитьСтроку(СтрокаОтветаXML);
// Переходим к разбору полезной нагрузки XML
Пока Чтение.Прочитать() Цикл
Если Чтение.ТипУзла = ТипУзлаXML.НачалоЭлемента И Чтение.Имя = "LoadDataResult" Тогда
Чтение.Прочитать();
ЗначениеОтвета = Чтение.Значение;
// Выполняем дальнейшую бизнес-логику в информационной базе
КонецЕсли;
КонецЦикла;
Чтение.Закрыть();
КонецПроцедуры
Если для интеграции критично использовать именно стандартный объект WSПрокси на стороне сервера, а конкретная персона пользователя на внешнем сервисе не играет роли (достаточно общей авторизации в домене компании), проанализируем настройку серверного окружения:
svc_1c_server).svc_1c_server.После перезапуска службы сервера 1С создание прокси на сервере с параметром ИспользоватьАутентификациюОС = Истина начнет передавать доменные учетные данные учетной записи службы, и ошибки авторизации исчезнут.
&НаСервере
Функция ПодключитьсяКВебСервисуПодСлужебнойУчеткой()
WSDL = "http://service.domain.local/Services/DataExchange.asmx?WSDL";
URIПространстваИмен = "http://tempuri.org/";
ИмяСервиса = "DataExchange";
ИмяПорта = "DataExchangeSoap";
// Создаем WS-определения
Определения = Новый WSОпределения(WSDL, , , , 15);
// Инициализируем WSПрокси с аутентификацией ОС службы сервера
Прокси = Новый WSПрокси(Определения, URIПространстваИмен, ИмяСервиса, ИмяПорта, , 30, , , Истина);
Возврат Прокси;
КонецФункции
Если внешний сервис разработан силами внутренней команды компании и допускает модификацию контрактов взаимодействия, рекомендуется отказаться от авторизации по Windows-сессии в пользу модели «От имени пользователя» (On-Behalf-Of). В этом случае подключение от 1С к сервису выполняется под единой сервисной учетной записью или статическим токеном доступа, а учетная запись сотрудника, инициировавшего действие, передается внутри вызова.
В коде 1С имя текущего пользователя домена можно получить платформенной функцией:
ТекущийДоменныйПользователь = ИмяПользователяОС();
Полученное значение передается входным параметром в операцию веб-сервиса, и внешний сервис фиксирует все операции именно за данным сотрудником. Это снимает зависимость от протоколов NTLM и Kerberos на стыке серверных компонентов и значительно упрощает отладку взаимодействия систем.
При использовании проверки подлинности Windows важно учитывать следующие требования доменной инфраструктуры: