При интеграции 1С с внешними системами через веб-сервисы часто возникает задача: получить WSDL-описание сервиса, доступ к которому защищен логином и паролем (Basic Authentication). Стандартный конструктор объекта WSОпределения, казалось бы, принимает логин и пароль, но они предназначены для авторизации при вызове самих операций сервиса, а не для получения его описания.
Рассмотрим ситуацию, когда при попытке создать объект WSОпределения (и конвертации XSD в XDTO), передавая URL в виде "https://site.com/service?wsdl", система возвращает ошибку авторизации (например, с кодом 401). Это означает, что сам WSDL-файл закрыт от анонимного доступа. Проанализируем, как обойти это ограничение и успешно загрузить схему.
Самый простой и быстрый способ решить эту задачу — встроить имя пользователя и пароль непосредственно в строку URL. Этот формат является стандартным для Basic-аутентификации и поддерживается многими HTTP-клиентами, включая внутренние механизмы платформы 1С.
Давайте разберем этот метод по шагам.
Подготовка строки URL.
Необходимо сформировать строку адреса в следующем формате:
https://<strong>логин</strong>:<strong>пароль</strong>@<strong>адрес_сервера</strong>/<strong>путь_к_сервису</strong>?wsdl
Здесь:
логин — имя пользователя для доступа.пароль — пароль для доступа.адрес_сервера/путь_к_сервису — основной адрес WSDL-описания.Важный момент: если в логине или пароле содержатся специальные символы (например, @, :, /, ?, #), их необходимо предварительно закодировать в формат URL (Percent-encoding). Для этого в 1С можно использовать функцию КодироватьСтроку() с параметром СпособКодированияСтроки.КодировкаURL.
Создание объекта WSОпределения.
Теперь создадим объект WSОпределения, передав в его конструктор подготовленную строку URL. Обратите внимание, что параметры Логин и Пароль в конструкторе можно оставить пустыми, так как авторизация для получения WSDL уже "зашита" в сам адрес.
Посмотрим на итоговый пример кода:
// Определяем учетные данные
Логин = "user_login";
Пароль = "user_password";
// Формируем полную строку URL с учетными данными
// Если в логине или пароле есть спецсимволы, их нужно кодировать:
// ЛогинДляURL = КодироватьСтроку(Логин, СпособКодированияСтроки.КодировкаURL);
// ПарольДляURL = КодироватьСтроку(Пароль, СпособКодированияСтроки.КодировкаURL);
// АдресСервиса = "https://" + ЛогинДляURL + ":" + ПарольДляURL + "@site.com/service?wsdl";
// Для простых логина и пароля без спецсимволов:
АдресСервиса = "https://" + Логин + ":" + Пароль + "@site.com/service?wsdl";
Попытка
// Создаем объект WSОпределения.
// В данном случае логин и пароль в конструкторе не обязательны,
// так как они уже есть в URL.
Определения = Новый WSОпределения(АдресСервиса);
// Если все прошло успешно, можно создавать прокси
Прокси = Новый WSПрокси(Определения, Определения.Сервисы[0].URIПространстваИмен, Определения.Сервисы[0].Имя, Определения.Сервисы[0].ТочкиПодключения[0].Имя);
// Дальнейшая работа с прокси...
// Прокси.Пользователь = Логин;
// Прокси.Пароль = Пароль;
Сообщить("WSDL-описание успешно загружено!");
Исключение
Сообщить("Не удалось загрузить WSDL-описание. Ошибка:");
Сообщить(ОписаниеОшибки());
КонецПопытки;
Этот метод отлично подходит для быстрой разработки и отладки. Однако хранение учетных данных в открытом виде (в отличие от Google OAuth 2.0) в строке URL может быть небезопасным, так как такие URL могут кэшироваться или попадать в логи прокси-серверов.
Этот способ более сложный (см. курс по HTTP-запросам), но и более гибкий и безопасный. Он позволяет полностью контролировать процесс HTTP-запроса, устанавливать нужные заголовки и работать с любыми видами аутентификации. Суть метода заключается в том, чтобы сначала скачать WSDL-файл как обычный текстовый файл с помощью объекта HTTPСоединение, сохранить его локально, а затем создать объект WSОпределения из этого файла.
Разберем этот процесс по шагам.
Настройка HTTP-соединения.
Создаем объект HTTPСоединение, указывая сервер, порт и, при необходимости, параметры защищенного соединения (SSL).
Формирование HTTP-запроса.
Создаем объект HTTPЗапрос. В заголовках этого запроса мы должны явно указать данные для Basic-аутентификации. Заголовок называется Authorization, а его значение формируется по схеме: "Basic " + Base64("логин:пароль").
Выполнение запроса и сохранение результата.
Выполняем GET-запрос методом Получить(). Ответ сервера (тело ответа) будет содержать XML-текст WSDL-описания. Этот текст нужно сохранить во временный файл.
Создание WSОпределения из файла.
На последнем шаге создаем объект WSОпределения, передавая в конструктор не URL, а путь к временному файлу, который мы только что создали.
Проанализируем пример кода для этого подхода:
// Определяем учетные данные и адрес
Логин = "user_login";
Пароль = "user_password";
ИмяСервера = "site.com";
ПутьКСервису = "/service?wsdl";
// 1. Настраиваем HTTP-соединение
// Для HTTPS используем ЗащищенноеСоединение
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(ИмяСервера, 443, , , , , ЗащищенноеСоединение);
// 2. Формируем HTTP-запрос с заголовком авторизации
Запрос = Новый HTTPЗапрос(ПутьКСервису);
// Кодируем "логин:пароль" в Base64
СтрокаАвторизации = "" + Логин + ":" + Пароль;
КодированнаяСтрока = Base64Строка(СтрокаАвторизации);
// Устанавливаем заголовок
Запрос.Заголовки.Вставить("Authorization", "Basic " + КодированнаяСтрока);
// 3. Выполняем запрос и сохраняем результат
ПутьКВременномуФайлу = ПолучитьИмяВременногоФайла("wsdl");
Попытка
// Получаем WSDL-файл и сохраняем его
Соединение.Получить(Запрос, ПутьКВременномуФайлу);
// 4. Создаем WSОпределения из локального файла
Определения = Новый WSОпределения(ПутьКВременномуФайлу);
// Создаем прокси
Прокси = Новый WSПрокси(Определения, Определения.Сервисы[0].URIПространстваИмен, Определения.Сервисы[0].Имя, Определения.Сервисы[0].ТочкиПодключения[0].Имя);
// Не забываем установить пользователя и пароль для будущих вызовов самого сервиса!
Прокси.Пользователь = Логин;
Прокси.Пароль = Пароль;
Сообщить("WSDL-описание успешно загружено из временного файла!");
Исключение
Сообщить("Не удалось выполнить HTTP-запрос или создать WSОпределения. Ошибка:");
Сообщить(ОписаниеОшибки());
КонецПопытки;
// Не забываем удалить временный файл после использования
Попытка
УдалитьФайлы(ПутьКВременномуФайлу);
Исключение
КонецПопытки;
Этот метод, хоть и требует больше кода, является более универсальным. Он позволяет работать со сложными сценариями аутентификации, управлять таймаутами, работать с cookie и другими аспектами протокола HTTP.
Мы рассмотрели два эффективных способа загрузки WSDL-описания веб-сервиса, требующего авторизации.
Выбор конкретного метода зависит от требований к вашей системе, политик безопасности и сложности веб-сервиса, с которым вы интегрируетесь. В большинстве случаев для Basic Authentication первого, более простого способа, оказывается вполне достаточно.