Как подключиться к веб-сервису в 1С при ошибках 403 и "Неверный формат WSDL"?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Рассмотрим ситуацию, с которой часто сталкиваются разработчики при интеграции 1С со сторонними системами (например, с SAP PI/PO). Внешняя организация предоставляет ссылку на WSDL-описание веб-сервиса и, возможно, сам WSDL в виде отдельного файла. При попытке открыть ссылку в браузере все работает (запрашивается логин и пароль), но при добавлении в конфигуратор через WS-ссылки возникает ошибка: WSDL должен содержать элемент definitions по причине: Неверный формат.

Если же мы пытаемся подключиться программно, используя конструктор WSОпределения, то получаем ошибку: При создании описания сервиса произошла ошибка. URL сервиса: Код ответа сервера: 403. Давайте разберем по шагам, почему так происходит и как правильно организовать подключение.

Выясним причину ошибки "Неверный формат WSDL"

Проанализируем механику работы платформы 1С, опираясь на основы, изложенные в курсе по HTTP-запросам. При добавлении WS-ссылки или вызове Новый WSОпределения по URL, платформа строго ожидает получить в ответ корректный XML-документ (WSDL-схему), корневым элементом которого является тег <definitions> или <wsdl:definitions>.

Ошибка "Неверный формат" означает, что 1С получает по указанной ссылке не XML, а обычную HTML-страницу. Чаще всего это страница заглушки с текстом ошибки 403 (Forbidden) или форма ввода логина и пароля от шлюза внешней системы. Парсер 1С пытается прочитать HTML-теги, естественно, не находит обязательный элемент определения веб-сервиса и прерывает работу с ошибкой.

Разберем причину ошибки 403 (Access Denied) в коде

Почему в браузере доступ есть, а 1С выдает ошибку 403? Тут кроется важный нюанс контекста выполнения. Когда мы открываем ссылку в браузере на рабочем компьютере, браузер автоматически применяет наши текущие пользовательские сессии, доменные учетные данные или клиентские сертификаты, установленные в личном хранилище Windows.

Когда же код инициализации выполняется на стороне сервера 1С:Предприятия (в фоновом задании или серверном модуле), он работает от имени учетной записи службы операционной системы (например, USR1CV8). В отличие от работы через WebSocket Клиент, у этого системного пользователя нет доступа к вашему личному хранилищу сертификатов.

Посмотрим на пример кода, который часто вызывает проблемы:


ssl1 = Новый ЗащищенноеСоединениеOpenSSL(
    Новый СертификатКлиентаWindows(СпособВыбораСертификатаWindows.Авто), 
    Новый СертификатыУдостоверяющихЦентровWindows
);
Определение = Новый WSОпределения("https://...", Пользователь, Пароль, , , ssl1);

Использование параметра СпособВыбораСертификатаWindows.Авто крайне ненадежно в серверном контексте 1С. Платформа может выбрать некорректный сертификат, либо вообще его не найти, если в хранилище службы пусто. Результат — отказ в доступе (403).

Как решить проблему: шаг первый — локальный WSDL-файл

Чтобы обойти проблему с получением WSDL по защищенному HTTPS соединению, воспользуемся локальным файлом (например, BC_SYS_CLNT_si_DataLoad_outb_syncService.wsdl), который нам прислала внешняя организация. Инициализировать WSОпределения из локального файла — абсолютно правильный подход.

Рассмотрим, как это выглядит в коде:


// Указываем путь к физическому файлу на диске сервера 1С
ПутьКФайлуWSDL = "C:\Integrations\BC_SYS_CLNT_si_DataLoad_outb_syncService.wsdl";

// Читаем определение сервиса из файла (без сетевых запросов)
Определение = Новый WSОпределения(ПутьКФайлуWSDL, Пользователь, Пароль, , , ssl1);

Это мгновенно избавит нас от ошибки 403 на этапе чтения структуры сервиса, так как серверу 1С не придется скачивать схему из интернета.

Как решить проблему: шаг второй — настройка WSПрокси

После успешного создания определения из файла, следующая задача — создать сам прокси для вызова методов. Здесь многие сталкиваются с ошибкой: Сервис не найден. Проанализируем типичный ошибочный код:


Прокси = Новый WSПрокси(Определение, " ""si_DataLoad_outb_syncService", "si_DataLoad_outb_syncServiceSoap");

Ошибка "Сервис не найден" возникает из-за неверно переданных параметров при инициализации WSПрокси. Во-первых, обратите внимание на синтаксическую ошибку (лишний пробел и двойная кавычка). Во-вторых, разработчики часто путают пространства имен и имена сервисов, что критично и при создании HTTP API сервисов.

Разберем параметры конструктора WSПрокси по шагам, что полезно знать для написания общего модуля организации HTTP сервиса. Вам необходимо открыть локальный файл WSDL в любом текстовом редакторе (например, в Notepad++) и найти три ключевых значения:

  1. URIПространстваИмен (второй параметр): Это не имя сервиса. Это URI пространства имен. Найдите в самом начале WSDL-файла корневой тег <wsdl:definitions> и скопируйте значение его атрибута targetNamespace. Обычно оно выглядит как URL (например, http://sap.com/xi/Company) или URN.
  2. ИмяСервиса (третий параметр): Прокрутите файл в самый низ. Найдите тег <wsdl:service>. Скопируйте точное значение атрибута name.
  3. ИмяТочкиПодключения (четвертый параметр): Внутри тега сервиса будет тег <wsdl:port>. Скопируйте значение его атрибута name.

Теперь создадим прокси правильно:


URIПространстваИмен = "http://sap.com/xi/ВашаКомпания/Интеграция"; // Значение из targetNamespace
ИмяСервиса          = "si_DataLoad_outb_syncService";              // Значение из wsdl:service name="..."
ИмяТочкиПодключения = "si_DataLoad_outb_syncPort";                 // Значение из wsdl:port name="..."

Прокси = Новый WSПрокси(Определение, URIПространстваИмен, ИмяСервиса, ИмяТочкиПодключения);

Как решить проблему: шаг третий — явное указание сертификата

Теперь, когда прокси успешно инициализирован, нам необходимо выполнить реальный запрос (вызвать операцию веб-сервиса). Вот тут 1С снова обратится в интернет, и если для доступа нужен клиентский сертификат, нам нужно передать его явно, а не через СертификатКлиентаWindows.

Для надежной работы на сервере рекомендуется экспортировать клиентский сертификат (с закрытым ключом) в файл формата .p12 или .pfx и положить его рядом с WSDL-файлом.

Посмотрим на итоговый пример настройки соединения:


// 1. Читаем клиентский сертификат из файла
ИмяФайлаСертификата = "C:\Integrations\client_cert.p12";
ПарольСертификата   = "MySecretPassword";
Сертификат = Новый СертификатКриптографии(ИмяФайлаСертификата, ПарольСертификата);

// 2. Настраиваем SSL-соединение
ssl1 = Новый ЗащищенноеСоединениеOpenSSL(Сертификат, Новый СертификатыУдостоверяющихЦентровОС);

// 3. Загружаем WSDL из локального файла
ПутьКФайлуWSDL = "C:\Integrations\BC_SYS_CLNT_si_DataLoad_outb_syncService.wsdl";
Определение = Новый WSОпределения(ПутьКФайлуWSDL, Пользователь, Пароль, , , ssl1);

// 4. Создаем WSПрокси, используя точные данные из текста WSDL
Прокси = Новый WSПрокси(Определение, URIПространстваИмен, ИмяСервиса, ИмяТочкиПодключения);

// 5. Обязательно указываем логин и пароль для Basic-авторизации, если она требуется поверх SSL
Прокси.Пользователь = Пользователь;
Прокси.Пароль       = Пароль;

// 6. Вызываем метод сервиса
Ответ = Прокси.ИмяВашейОперации(ПараметрыЗапроса);

Используя этот пошаговый алгоритм, мы исключаем ошибки автоматического поиска сертификатов в хранилище операционной системы и обходим проблему блокировки при первичном чтении WSDL-схемы. Внимательно проверяйте пространства имен в WSDL, и ваше подключение к сторонним веб-сервисам заработает стабильно.

← На главную