Как скачать WSDL-описание веб-сервиса по защищенному соединению (HTTPS) в 1С

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

При интеграции 1С с внешними информационными системами разработчики часто сталкиваются с необходимостью подключить сторонний веб-сервис. Классический способ начать работу с ним — получить его WSDL-описание (Web Services Description Language). Однако при попытке скачать WSDL-файл напрямую по ссылке, использующей защищенный протокол HTTPS, программисты нередко получают системную ошибку: «Ошибка работы с Интернет: Удаленный узел не прошел проверку» или «Ошибка доступа к файлу».

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

Выясняем причину: почему падает стандартный метод КопироватьФайл?

Начинающие разработчики часто пытаются решить задачу «в лоб», используя простую встроенную функцию КопироватьФайл. Код выглядит следующим образом:


ИмяВременногоФайла = ПолучитьИмяВременногоФайла("wsdl");
КопироватьФайл("https://3dsec.sberbank.ru/payment/webservices/merchant-ws?wsdl", ИмяВременногоФайла);

При работе с протоколом HTTP этот метод может сработать. Однако при переходе на HTTPS платформа инициирует защищенное SSL/TLS-соединение. Процедура КопироватьФайл не имеет встроенных параметров для тонкой настройки TLS-соединения и полностью полагается на настройки операционной системы.

Если удаленный веб-сервер (например, шлюз Сбербанка) использует SSL-сертификаты, выданные удостоверяющим центром, который не входит в стандартный список доверенных сертификатов вашей операционной системы или платформы 1С, проверка безопасности проваливается. Платформа прерывает соединение, выдавая ошибку: «Удаленный узел не прошел проверку».

Особенно актуальной эта проблема стала после перевода многих российских государственных и коммерческих порталов (включая Сбербанк, Госуслуги и др.) на сертификаты Национального удостоверяющего центра (НУЦ) Минцифры России. По умолчанию данные корневые сертификаты отсутствуют в большинстве операционных систем семейства Windows и Linux, а также в стандартном дистрибутиве платформы 1С.


Решение №1: Использование HTTPСоединения с защищенным соединением OpenSSL

Для обхода ограничений стандартного копирования файлов нам необходимо использовать объект HTTPСоединение. Он позволяет явно указать платформе, что соединение должно быть защищенным, и гибко настроить параметры безопасности.

Рассмотрим по шагам комплексный алгоритм скачивания файла, предложенный в обсуждении. Он включает в себя разбор URL-адреса, инициализацию защищенного SSL-соединения и обработку кодов состояния HTTP-ответа.

Шаг 1. Разбор строки URI (адреса ресурса)

Прежде чем создать объект HTTP-соединения, нам нужно разделить полный адрес веб-сервиса (например, https://3dsec.sberbank.ru/payment/webservices/merchant-ws?wsdl) на составляющие: имя сервера (хост) и путь к ресурсу на сервере. Если в вашей конфигурации используется Библиотека Стандартных Подсистем (БСП), вы можете применить готовую функцию ОбщегоНазначенияКлиентСервер.ПолучитьСтруктуруURI(). Если БСП отсутствует, напишем собственную вспомогательную функцию:


&НаКлиенте
Функция ПолучитьСтруктуруURI(Знач СтрокаURI) Экспорт
    СтрокаURI = СокрЛП(СтрокаURI);
    
    // Выделяем схему (протокол)
    Схема = "";
    Позиция = Найти(СтрокаURI, "://");
    Если Позиция > 0 Тогда
        Схема = НРег(Лев(СтрокаURI, Позиция - 1));
        СтрокаURI = Сред(СтрокаURI, Позиция + 3);
    КонецЕсли;
    
    // Выделяем строку соединения и путь на сервере
    СтрокаСоединения = СтрокаURI;
    ПутьНаСервере = "";
    Позиция = Найти(СтрокаСоединения, "/");
    Если Позиция > 0 Тогда
        ПутьНаСервере = Сред(СтрокаСоединения, Позиция + 1);
        СтрокаСоединения = Lев(СтрокаСоединения, Позиция - 1);
    КонецЕсли;
        
    // Выделяем информацию авторизации (если есть)
    СтрокаАвторизации = "";
    ИмяСервера = СтрокаСоединения;
    Позиция = Найти(СтрокаСоединения, "@");
    Если Позиция > 0 Тогда
        СтрокаАвторизации = Лев(СтрокаСоединения, Позиция - 1);
        ИмяСервера = Сред(СтрокаСоединения, Позиция + 1);
    КонецЕсли;
    
    // Разделяем логин и пароль
    Логин = СтрокаАвторизации;
    Пароль = "";
    Позиция = Найти(СтрокаАвторизации, ":");
    Если Позиция > 0 Тогда
        Логин = Лев(СтрокаАвторизации, Позиция - 1);
        Пароль = Сред(СтрокаАвторизации, Позиция + 1);
    КонецЕсли;
    
    // Разделяем хост и порт
    Хост = ИмяСервера;
    Порт = "";
    Позиция = Найти(ИмяСервера, ":");
    Если Позиция > 0 Тогда
        Хост = Лев(ИмяСервера, Позиция - 1);
        Порт = Сред(ИмяСервера, Позиция + 1);
    КонецЕсли;
    
    Результат = Новый Структура;
    Результат.Вставить("Схема", Схема);
    Результат.Вставить("Логин", Логин);
    Результат.Вставить("Пароль", Пароль);
    Результат.Вставить("ИмяСервера", ИмяСервера);
    Результат.Вставить("Хост", Хост);
    Результат.Вставить("Порт", ?(Порт <> "", Число(Порт), Неопределено));
    Результат.Вставить("ПутьНаСервере", ПутьНаСервере);
    
    Возврат Результат;
КонецФункции

Шаг 2. Выполнение защищенного запроса

Теперь создадим основную процедуру, которая инициализирует объект ЗащищенноеСоединениеOpenSSL, выполняет GET-запрос к серверу и сохраняет результат в указанный файл на диске.


&НаКлиенте
Процедура ВыполнитьHTTPЗапрос(ПолныйАдресРесурса, ИмяВременногоФайла)
    
    // Шаг 2.1. Разбираем URI
    СтруктураURI = ПолучитьСтруктуруURI(ПолныйАдресРесурса); 
    
    // Шаг 2.2. Создаем защищенное соединение. 
    // Если параметры пустые, будут использоваться системные настройки сертификатов.
    ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
    
    // Инициализируем HTTPСоединение с использованием защищенного SSL
    HTTPСоединение = Новый HTTPСоединение(
        СтруктураURI.Хост, 
        СтруктураURI.Порт, 
        СтруктураURI.Логин, 
        СтруктураURI.Пароль, 
        , // Прокси
        , // Таймаут
        ЗащищенноеСоединение
    );
    
    // Создаем запрос к конкретному пути на сервере
    HTTPЗапрос = Новый HTTPЗапрос(СтруктураURI.ПутьНаСервере); 
    
    Попытка
        // Отправляем запрос и указываем файл, куда нужно записать тело ответа (наш WSDL)
        Результат = HTTPСоединение.Получить(HTTPЗапрос, ИмяВременногоФайла);
    Исключение
        Сообщить("Произошла сетевая ошибка при попытке связаться с сервером!");
        ВызватьИсключение;
    КонецПопытки;
    
    // Шаг 2.3. Обрабатываем полученные статус-коды HTTP
    КодСостояния = Результат.КодСостояния;
    
    // Ошибки клиента (например, 404 - файл не найден, 401 - нет доступа)
    Если КодСостояния >= 400 И КодСостояния < 500 Тогда
         Сообщить("Ошибка запроса. Код статуса: " + КодСостояния);
         Возврат;
    КонецЕсли;
    
    // Ошибки самого сервера (500, 503 и т.д.)
    Если КодСостояния >= 500 И КодСостояния < 600 Тогда
         Сообщить("Внутренняя ошибка сервера. Код статуса: " + КодСостояния);
         Возврат;
    КонецЕсли;
    
    // Обработка перенаправлений (3xx)
    Если КодСостояния >= 300 И КодСостояния < 400 Тогда
         Сообщить("Обнаружено перенаправление ресурса. Код статуса: " + КодСостояния);
         Если КодСостояния = 301 Или КодСостояния = 302 Тогда
              НовыйАдрес = Результат.Заголовки.Получить("Location");
              Если НовыйАдрес <> Неопределено Тогда
                  Сообщить("Перенаправляем запрос на новый адрес: " + НовыйАдрес);
                  // Рекурсивно вызываем функцию по новому адресу
                  ВыполнитьHTTPЗапрос(НовыйАдрес, ИмяВременногоФайла);
              Иначе
                  Сообщить("Сервер вернул статус перенаправления, но не указал новый URL!");
              КонецЕсли;
         КонецЕсли;
         Возврат;
    КонецЕсли;
    
    // Успешное выполнение запроса (2xx)
    Если КодСостояния >= 200 И КодСостояния < 300 Тогда 
         Сообщить("Файл успешно скачан! Код статуса: " + КодСостояния);    
    КонецЕсли; 
    
КонецПроцедуры

Шаг 3. Инициация процесса загрузки

Для запуска процесса достаточно получить путь для временного файла и вызвать нашу процедуру:


&НаКлиенте
Процедура ЗагрузитьWSDL(Команда)
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("wsdl");
    АдресWSDL = "https://3dsec.sberbank.ru/payment/webservices/merchant-ws?wsdl";    
    
    ВыполнитьHTTPЗапрос(АдресWSDL, ИмяВременногоФайла);
    
    // Дальнейшая работа с файлом на диске
    // Например, ЧтениеXML.ОткрытьФайл(ИмяВременногоФайла);
КонецПроцедуры

Решение №2: Использование динамических WSОпределений (без скачивания файлов)

Если конечной целью скачивания WSDL является создание WSПрокси для последующего вызова методов веб-сервиса, то скачивать файл на жесткий диск вообще не обязательно. Платформа 1С умеет динамически считывать схему веб-сервиса прямо из интернета и на лету строить структуру вызовов.

Для этого используется объект WSОпределения, в конструктор которого мы также можем передать параметры безопасности. Это значительно сокращает объем программного кода и избавляет от необходимости парсить XML-файлы вручную.

Рассмотрим, как выглядит динамическое подключение:


// Создаем объект защищенного соединения
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();

Попытка
    // Платформа сама скачает WSDL, проанализирует его структуру и создаст описания типов
    Определения = Новый WSОпределения(
        "https://3dsec.sberbank.ru/payment/webservices/merchant-ws?wsdl", 
        , // Имя пользователя веб-сервиса
        , // Пароль пользователя веб-сервиса
        , // Таймаут
        ЗащищенноеСоединение
    );
    
    // Создаем прокси-класс для вызова методов
    // Имена пространства, сервиса и точки подключения берутся из структуры WSDL
    Прокси = Новый WSПрокси(
        Определения, 
        "http://payment.webservices.merchant.sberbank.ru/", // Пространство имен
        "MerchantService",                                 // Имя сервиса
        "MerchantPort"                                     // Точка подключения
    );
    
    Сообщить("Подключение к веб-сервису успешно установлено!");
Исключение
    Сообщить("Не удалось инициализировать веб-сервис: " + ОписаниеОшибки());
КонецПопытки

Что делать, если ошибка «Удаленный узел не прошел проверку» сохраняется?

Если даже при использовании объекта ЗащищенноеСоединениеOpenSSL вы продолжаете получать ошибку проверки удаленного узла, это означает, что в вашей операционной системе или в платформе 1С отсутствуют доверенные корневые сертификаты выпускающего центра (например, Минцифры РФ).

Для исправления этой системной проблемы выполните следующие административные действия:

  1. Установите корневые сертификаты в ОС:

    Скачайте официальные корневые сертификаты НУЦ Минцифры России (обычно это два файла: корневой Russian Trusted Root CA и выпускающий Russian Trusted Sub CA). Установите их в операционную систему в хранилище «Доверенные корневые центры сертификации».

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

  2. Обновите файл cacert.pem в платформе 1С:

    Платформа 1С для работы с защищенным соединением использует собственный встроенный список доверенных сертификатов, расположенный в файле cacert.pem. Этот файл находится в каталоге установленной платформы, например: C:\Program Files\1cv8\[ВерсияПлатформы]\bin\cacert.pem.

    Вы можете открыть этот файл текстовым редактором и дописать в самый конец текстовое содержимое (в формате PEM) российских корневых сертификатов, либо скачать уже обновленный файл cacert.pem с официального портала ИТС 1С и заменить им старый файл в каталоге bin платформы на сервере и клиенте.

  3. Игнорирование проверки отзыва сертификатов:

    Иногда веб-сервер успешно проходит проверку, но платформа не может получить доступ к серверам проверки списков отзыва сертификатов (CRL), из-за чего соединение все равно блокируется. Чтобы отключить эту строгую проверку, вы можете добавить в конфигурационный файл платформы conf.cfg (находится в каталоге bin/conf установленной версии 1С) следующую строку настроек:

    IgnoreServerCertificatesChainRevocationSoftFail=true

Применение данных методик в совокупности позволит вам стабильно и безопасно работать с любыми защищенными веб-сервисами непосредственно из программного кода 1С, избегая непредвиденных ошибок при скачивании схем данных и вызове удаленных методов.

← На главную