При интеграции 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С.
Для обхода ограничений стандартного копирования файлов нам необходимо использовать объект HTTPСоединение. Он позволяет явно указать платформе, что соединение должно быть защищенным, и гибко настроить параметры безопасности.
Рассмотрим по шагам комплексный алгоритм скачивания файла, предложенный в обсуждении. Он включает в себя разбор URL-адреса, инициализацию защищенного SSL-соединения и обработку кодов состояния HTTP-ответа.
Прежде чем создать объект 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);
КонецЕсли;
Результат = Новый Структура;
Результат.Вставить("Схема", Схема);
Результат.Вставить("Логин", Логин);
Результат.Вставить("Пароль", Пароль);
Результат.Вставить("ИмяСервера", ИмяСервера);
Результат.Вставить("Хост", Хост);
Результат.Вставить("Порт", ?(Порт <> "", Число(Порт), Неопределено));
Результат.Вставить("ПутьНаСервере", ПутьНаСервере);
Возврат Результат;
КонецФункции
Теперь создадим основную процедуру, которая инициализирует объект ЗащищенноеСоединение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 Тогда
Сообщить("Файл успешно скачан! Код статуса: " + КодСостояния);
КонецЕсли;
КонецПроцедуры
Для запуска процесса достаточно получить путь для временного файла и вызвать нашу процедуру:
&НаКлиенте
Процедура ЗагрузитьWSDL(Команда)
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("wsdl");
АдресWSDL = "https://3dsec.sberbank.ru/payment/webservices/merchant-ws?wsdl";
ВыполнитьHTTPЗапрос(АдресWSDL, ИмяВременногоФайла);
// Дальнейшая работа с файлом на диске
// Например, ЧтениеXML.ОткрытьФайл(ИмяВременногоФайла);
КонецПроцедуры
Если конечной целью скачивания 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С отсутствуют доверенные корневые сертификаты выпускающего центра (например, Минцифры РФ).
Для исправления этой системной проблемы выполните следующие административные действия:
Скачайте официальные корневые сертификаты НУЦ Минцифры России (обычно это два файла: корневой Russian Trusted Root CA и выпускающий Russian Trusted Sub CA). Установите их в операционную систему в хранилище «Доверенные корневые центры сертификации».
Важно: Если ваша база 1С работает в клиент-серверном режиме, эти сертификаты должны быть обязательно установлены на сервере 1С под учетной записью, от имени которой запущена служба сервера 1С (например, USR1CV8).
Платформа 1С для работы с защищенным соединением использует собственный встроенный список доверенных сертификатов, расположенный в файле cacert.pem. Этот файл находится в каталоге установленной платформы, например: C:\Program Files\1cv8\[ВерсияПлатформы]\bin\cacert.pem.
Вы можете открыть этот файл текстовым редактором и дописать в самый конец текстовое содержимое (в формате PEM) российских корневых сертификатов, либо скачать уже обновленный файл cacert.pem с официального портала ИТС 1С и заменить им старый файл в каталоге bin платформы на сервере и клиенте.
Иногда веб-сервер успешно проходит проверку, но платформа не может получить доступ к серверам проверки списков отзыва сертификатов (CRL), из-за чего соединение все равно блокируется. Чтобы отключить эту строгую проверку, вы можете добавить в конфигурационный файл платформы conf.cfg (находится в каталоге bin/conf установленной версии 1С) следующую строку настроек:
IgnoreServerCertificatesChainRevocationSoftFail=true
Применение данных методик в совокупности позволит вам стабильно и безопасно работать с любыми защищенными веб-сервисами непосредственно из программного кода 1С, избегая непредвиденных ошибок при скачивании схем данных и вызове удаленных методов.