При работе на платформе 1С:Предприятие 8.1 программисты часто сталкиваются с существенными ограничениями встроенного объекта HTTPСоединение. Одной из наиболее острых проблем является реализация защищенного соединения (HTTPS) с использованием клиентских сертификатов. В современных версиях платформы (8.3.x) для этого предусмотрены специализированные объекты вроде ЗащищенноеСоединениеOpenSSL, однако в версии 8.1 функционал крайне ограничен. Рассмотрим, почему стандартные методы не работают и как решить эту задачу с помощью внешних инструментов.
В платформе 8.1 конструктор объекта HTTPСоединение принимает параметр ЗащищенноеСоединение, который может принимать лишь логическое значение Истина или Ложь. Мы не можем явно указать, какой сертификат использовать, или настроить параметры TLS. Платформа в данном случае полностью полагается на настройки операционной системы и системное хранилище сертификатов Windows.
Проанализируем типичную ситуацию: при попытке инициализировать соединение с параметром ЗащищенноеСоединение = Истина, система может аварийно завершить работу или выдать неинформативную ошибку, которую даже не всегда удается перехватить блоком Попытка ... Исключение. Это происходит из-за того, что механизм WinInet, используемый в 8.1, пытается автоматически подобрать сертификат из личного хранилища текущего пользователя. Если сертификатов несколько, требуется ввод пароля или сервер требует специфический протокол (например, TLS 1.2), штатный объект просто «сдается».
Наиболее надежным и проверенным способом решения данной задачи в 1С 8.1 является использование системного COM-объекта WinHttp.WinHttpRequest.5.1. Этот объект предоставляет гораздо больше контроля над процессом передачи данных, включая возможность явного указания клиентского сертификата и настройки параметров безопасности. Разберем по шагам реализацию этого метода.
Рассмотрим пример кода, который позволяет отправить запрос с использованием конкретного сертификата:
Процедура ЗапросКСервисуНаПлатформе1С8_1(Сервер, Сервис, СертификатИмя, ТипЗапроса, ТекстЗапроса)
// Создаем основной объект для выполнения HTTP-запросов
WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
// Настраиваем использование кодировки UTF-8 для корректной передачи данных
WinHttp.Option(2, "UTF-8");
// Указываем имя сертификата, который должен быть предварительно установлен
// в хранилище сертификатов Windows
WinHttp.SetClientCertificate(СертификатИмя);
// Устанавливаем тайм-ауты (разрешение имен, соединение, отправка, получение)
WinHttp.SetTimeouts(10000, 10000, 30000, 30000);
// В некоторых случаях для корректной работы с кодировками и специфическими флагами
// удобно использовать MSScriptControl
Скрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
Скрипт.Language = "javascript";
Скрипт.AddObject("WinHttp", WinHttp);
// Принудительно устанавливаем опции через скрипт
Скрипт.Eval("WinHttp.Option(2) = ""utf-8"""); // Кодировка
Скрипт.Eval("WinHttp.Option(4) = 13056"); // Игнорирование ошибок сертификатов (если нужно)
Скрипт.Eval("WinHttp.Option(6) = true"); // Разрешить редиректы
Скрипт.Eval("WinHttp.Option(12) = true"); // Использовать современные протоколы безопасности
// Открываем соединение (ТипЗапроса: "GET", "POST", "PUT" и т.д.)
WinHttp.Open(ТипЗапроса, Сервер + Сервис, 0);
// Устанавливаем заголовки, если работаем с JSON
WinHttp.SetRequestHeader("Content-Type", "application/json;charset=UTF-8");
// Отправляем тело запроса
WinHttp.Send(ТекстЗапроса);
// Получаем ответ сервера
Ответ = WinHttp.ResponseText;
Сообщить(Ответ);
КонецПроцедуры
Выясним причину использования дополнительных флагов Option. В 1С 8.1 работа с типами данных в COM-объектах иногда может приводить к ошибкам, поэтому использование MSScriptControl позволяет гарантированно передать нужные числовые значения флагов.
Важные опции WinHttp:
13056 позволяет игнорировать распространенные ошибки SSL, такие как несовпадение имени хоста или самоподписанный сертификат. Это полезно при работе с тестовыми стендами.2048.Проанализируем ситуацию, когда код выполняется в контексте сервера 1С. Это важный момент, так как объект WinHttp будет обращаться к хранилищу сертификатов того пользователя, под которым запущена служба 1С (например, USR1CV81). Если вы установили сертификат под своей учетной записью администратора («Текущий пользователь»), серверная часть 1С его просто не увидит.
Для стабильной работы рекомендуется:
Посмотрим на пример формирования заголовков. В сообщениях форума упоминалось, что строка Заголовки.Вставить("Content-Type", "application/json;charset=UTF-8") может вызывать ошибку. В 8.1 объект Соответствие работает корректно, но стоит помнить, что сама платформа не имеет встроенных функций ПрочитатьJSON или ЗаписатьJSON. Вам придется формировать тело запроса вручную, объединяя строки, и крайне внимательно следить за кодировкой. Используйте WinHttp.Send() с корректно подготовленной строкой, предварительно убедившись, что сервер ожидает именно такой формат данных.
Если работа с WinHttp кажется слишком сложной или сертификаты требуют специфического взаимодействия (например, аппаратные ключи), рассмотрим альтернативные пути:
HTTPЗапрос и ЗащищенноеСоединениеOpenSSL.Таким образом, несмотря на почтенный возраст платформы 8.1, задача передачи клиентских сертификатов решаема. Использование WinHttp.WinHttpRequest.5.1 является наиболее гибким и мощным инструментом, позволяющим обойти архитектурные ограничения старых версий 1С.