При интеграции платформы 1С с веб-сервисами, сайтами или внутренними ресурсами через VPN разработчики часто сталкиваются с ситуацией, когда запрос из обычного браузера выполняется корректно, а из 1С вылетает с ошибкой. Наиболее распространенными проявлениями такой проблемы являются системная ошибка -2146697211 (а также 0x800C000D), сообщение «Peer certificate cannot be authenticated with known CA certificates» или исключение «Недопустимый или неправильный центр сертификации» при вызове метода send.
В этой статье мы подробно разберем причины возникновения подобных сбоев и проанализируем варианты настройки взаимодействия с защищенными ресурсами (HTTPS) как с использованием штатных механизмов 1С, так и через внешние COM-объекты Windows.
Проанализируем основные причины, по которым безопасное соединение не может быть установлено:
MSXML2.XMLHTTP базируется на системной библиотеке WinINet и использует настройки текущего пользователя Windows. В то же время MSXML2.ServerXMLHTTP работает через службу WinHTTP, а код на стороне сервера 1С исполняется от имени системной учетной записи (например, usr1cv8), у которой нет доступа к пользовательскому хранилищу сертификатов.В современных версиях платформы 1С использование COM-объектов не является обязательным. Платформа предоставляет встроенный объект HTTPСоединение, работающий на всех поддерживаемых операционных системах. Если целевой веб-сервис использует корпоративный или самоподписанный сертификат, проверку валидности сертификата можно программно отключить с помощью объекта НастройкаЗащищенногоСоединенияOpenSSL.
Рассмотрим пример создания защищенного соединения без проверки цепочки сертификатов:
// Создаем настройку защищенного соединения OpenSSL
НастройкаЗащищенного = Новый НастройкаЗащищенногоСоединенияOpenSSL();
НастройкаЗащищенного.ИгнорироватьОшибкиПроверкиСертификата = Истина;
// Инициализируем защищенное соединение
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(НастройкаЗащищенного);
// Указываем параметры подключения
Сервер = "internal.domain.local";
Порт = 443;
Логин = "admin";
Пароль = "password";
Прокси = Неопределено;
Таймаут = 30;
// Устанавливаем HTTP-соединение
Соединение = Новый HTTPСоединение(
Сервер,
Порт,
Логин,
Пароль,
Прокси,
Таймаут,
ЗащищенноеСоединение
);
// Заполняем заголовки и отправляем запрос
Заголовки = Новый Соответствие();
Заголовки.Вставить("Content-Type", "application/x-www-form-urlencoded");
Запрос = Новый HTTPЗапрос("/pp/login.spring-json", Заголовки);
Запрос.УстановитьТелоИзСтроки("user=" + Логин + "&pwd=" + Пароль);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Сообщить("Код состояния: " + Ответ.КодСостояния);
Если решение требует применения COM-объектов системы Windows, вместо стандартного MSXML2.XMLHTTP рекомендуется использовать MSXML2.ServerXMLHTTP.6.0. Данный объект специально разработан для серверных процессов и предоставляет метод setOption, с помощью которого можно отключить проверку ошибок SSL-сертификатов.
Посмотрим на пример кода с отключением проверки валидности сертификатов (флаг 13056 / 0x3300):
URL = "https://internal.domain.local/pp/login.spring-json";
ТекстЗапроса = "login.spring-json?user=" + Логин + "&pwd=" + Пароль;
Попытка
ComObj = Новый COMОбъект("MSXML2.ServerXMLHTTP.6.0");
// Опция 2 с флагом 13056 игнорирует все ошибки SSL-сертификатов
// (несоответствие имени, просроченный или неизвестный CA)
ComObj.setOption(2, 13056);
// Устанавливаем таймауты: resolve, connect, send, receive (в миллисекундах)
ComObj.setTimeouts(5000, 5000, 10000, 10000);
ComObj.open("POST", URL, Ложь);
ComObj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ComObj.send(ТекстЗапроса);
Если ComObj.status = 200 Тогда
Сообщить("Запрос успешно выполнен. Ответ: " + ComObj.responseText);
Иначе
Сообщить("Сервер вернул статус: " + Строка(ComObj.status));
КонецЕсли;
Исключение
Сообщить("Ошибка при выполнении запроса: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
Альтернативным и более гибким инструментом в ОС Windows является объект WinHttp.WinHttpRequest.5.1. Он также позволяет обходить ошибки сертификации с помощью установки свойства Option(4).
Разберем пример реализации запроса:
URL = "https://internal.domain.local/api/data";
Попытка
WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
// Игнорировать ошибки SSL (WinHttpRequestOption_SslErrorIgnoreFlags = 4)
// Значение 13056 скрывает ошибки неизвестного CA, несоответствия имен и даты
WinHttp.Option(4) = 13056;
WinHttp.Open("GET", URL, Ложь);
WinHttp.setRequestHeader("Content-Type", "application/json");
WinHttp.Send();
Сообщить("Статус ответа: " + WinHttp.Status);
Сообщить("Текст ответа: " + WinHttp.ResponseText);
Исключение
Сообщить("Не удалось выполнить запрос: " + ОписаниеОшибки());
КонецПопытки;
Отключение проверки сертификатов является быстрым, но не всегда безопасным решением. Для корректной работы без отключения проверок необходимо импортировать корневой сертификат локального центра сертификации в ОС:
.cer или .crt).certlm.msc для локального компьютера).usr1cv8) имеет доступ к данному хранилищу, либо перезапустите службу сервера 1С после импорта.Подведем итоги: для решения проблем с HTTPS-запросами в 1С предпочтительно использовать штатный объект HTTPСоединение с настройкой OpenSSL. Если необходима совместимость со старым кодом на базе COM-объектов Windows, переходите на MSXML2.ServerXMLHTTP.6.0 или WinHttp.WinHttpRequest.5.1 с явным указанием флагов игнорирования ошибок SSL.