При интеграции систем автоматизации на базе устаревших версий платформ 1С (например, 1С:Предприятие 8.2.16.362) с современными внешними веб-сервисами разработчики неизбежно сталкиваются с аппаратными и программными ограничениями. Встроенные механизмы платформы 8.2 не поддерживают современные объекты HTTPЗапрос и объект инициализации защищенного соединения ЗащищенноеСоединениеOpenSSL, которые появились только в версии 8.3. Попытки использовать штатное HTTPСоединение часто приводят к ошибкам перенаправления (редирект с кодом 301/302) или полному отказу соединения из-за несовместимости протоколов шифрования SSL/TLS.
В рамках этой статьи мы подробно разберем, как обойти данные ограничения, настроить надежную авторизацию через API, правильно обработать куки (Cookies), побороть проблему с перенаправлением на HTTPS (TLS 1.2) и заставить устаревшую платформу корректно обмениваться данными с современным веб-интерфейсом.
Рассмотрим стандартную ситуацию, с которой сталкивается разработчик. При попытке выполнить следующий код:
Путь = КаталогВременныхФайлов() + "details.html";
WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("GET", Сервер, 0);
WinHttp.SetCredentials(Логин, Пароль, 0);
WinHttp.send();
В ответ вместо ожидаемых данных мы получаем HTML-код страницы авторизации («Вход в систему»). Проанализируем, почему метод SetCredentials не приносит результата.
Дело в том, что метод SetCredentials(Логин, Пароль, 0) предназначен исключительно для стандартной HTTP-авторизации (Basic, Digest или NTLM/Kerberos). При такой схеме сервер при попытке неавторизованного доступа возвращает HTTP-заголовок WWW-Authenticate с кодом состояния 401 Unauthorized, сообщая клиенту о необходимости передать учетные данные. Если же сайт настроен на работу через обычную форму ввода логина и пароля, он не возвращает ошибку 401, а просто перенаправляет пользователя на HTML-страницу авторизации (Form-Based Authentication).
В этом случае нам необходимо имитировать действия пользователя в браузере. Выполним следующие шаги:
POST-запрос на специальный адрес (например, /login или /auth.php).application/x-www-form-urlencoded (например, user=login&pass=password) или application/json.POST-запрос с учетными данными, а затем выполним целевой GET-запрос для получения файла details.html.Поскольку объект WinHttp.WinHttpRequest.5.1 автоматически сохраняет полученные от сервера Cookie в рамках одного запущенного COM-объекта, последующий GET-запрос выполнится уже в авторизованной сессии.
Посмотрим на практический пример реализации авторизации на основе веб-формы:
// Создаем единый COM-объект для всей сессии обмена
WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
// 1. Отправляем POST-запрос авторизации
URLАвторизации = "https://mysite.com/auth/login"; // Замените на реальный URL обработчика формы
WinHttp.Open("POST", URLАвторизации, Ложь);
WinHttp.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// Формируем тело запроса с параметрами формы
ТелоЗапроса = "username=" + Логин + "&password=" + Пароль;
WinHttp.Send(ТелоЗапроса);
// Проверяем успешность авторизации
Если WinHttp.Status <> 200 Тогда
ВызватьИсключение "Ошибка авторизации на сервере! Код ответа: " + WinHttp.Status;
КонецЕсли;
// 2. Теперь выполняем GET-запрос к защищенной странице
// Объект WinHttp автоматически прикрепит полученные Cookie авторизации
URLДанных = "https://mysite.com/details.html";
WinHttp.Open("GET", URLДанных, Ложь);
WinHttp.Send();
Если WinHttp.Status = 200 Тогда
// Сохраняем полученный результат во временный файл
ПутьКФайлу = КаталогВременныхФайлов() + "details.html";
ЗаписьТекста = Новый ЗаписьТекста(ПутьКФайлу, КодировкаТекста.UTF8);
ЗаписьТекста.Записать(WinHttp.ResponseText);
ЗаписьТекста.Закрыть();
Сообщить("Данные успешно получены и сохранены!");
Иначе
Сообщить("Не удалось получить данные. Код ошибки: " + WinHttp.Status);
КонецЕсли;
При использовании штатного метода HTTPСоединение на старых релизах платформы 1С часто возникает ошибка перенаправления (код состояния 301 или 302). Это происходит, когда веб-сервер принудительно переводит пользователя с небезопасного протокола HTTP на защищенный HTTPS. Платформа 8.2 не всегда умеет обрабатывать такие редиректы «на лету» автоматически.
Для решения этой проблемы при работе через COM-объект WinHttp нам потребуется тонкая настройка параметров соединения. Однако в 1С невозможно напрямую обратиться к индексируемым свойствам COM-объекта вроде WinHttp.Option(4) = ... — это вызовет ошибку синтаксиса встроенного языка 1С. Чтобы обойти это досадное ограничение, мы можем применить обходной путь с использованием объекта выполнения скриптов MSScriptControl.ScriptControl.
Рассмотрим, как это реализовать на практике:
WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
// Создаем скрипт-контрол для выполнения JavaScript-кода
Скрипт = Новый COMОбъект("MSScriptControl.ScriptControl");
Скрипт.Language = "javascript";
Скрипт.AddObject("WinHttp", WinHttp);
// Опция 4 (SslErrorIgnoreFlags) позволяет игнорировать ошибки безопасности SSL
// Значение 13056 отключает проверку несоответствия имени сертификата и неизвестных издателей
Скрипт.Eval("WinHttp.Option(4) = 13056");
// Опция 6 (EnableRedirects) разрешает автоматический редирект (включая переходы http -> https)
Скрипт.Eval("WinHttp.Option(6) = true");
// Опция 12 (EnableHttpsToHttpRedirects) разрешает обратные редиректы при необходимости
Скрипт.Eval("WinHttp.Option(12) = true");
// Опция 9 определяет используемые протоколы безопасного соединения (SecureProtocols)
// Значение 2048 принудительно включает поддержку TLS 1.2
Скрипт.Eval("WinHttp.Option(9) = 2048");
Использование связки с MSScriptControl.ScriptControl дает разработчику полный контроль над сетевым поведением компоненты WinHTTP прямо из кода 1С 8.2, позволяя обходить любые ограничения безопасности старой платформы.
Если целевой веб-сервер требует исключительно современный протокол шифрования TLS 1.2 (или выше), а ваша операционная система Windows (особенно устаревшие Windows Server 2008 R2, Windows 7) не настроена на его поддержку по умолчанию для системных веб-компонент, вызовы WinHttp.Send() будут завершаться системной ошибкой инициализации SSL-соединения.
Чтобы решить эту проблему, необходимо внести изменения в системный реестр Windows на компьютере, где выполняется код 1С (на рабочем месте пользователя или на сервере приложений 1С):
regedit).HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols.TLS 1.2, а внутри него подраздел Client.Client добавьте два параметра типа DWORD (32 бита):
DisabledByDefault со значением 0Enabled со значением 1HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttpHKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Internet Settings\WinHttpDefaultSecureProtocols и установите для него шестнадцатеричное значение 0x00000800 (что соответствует принудительной активации TLS 1.2).После внесения изменений в реестр рекомендуется перезагрузить компьютер (или службу сервера 1С:Предприятия), чтобы изменения вступили в силу.
Бывают ситуации, когда обновить операционную систему или внести изменения в системный реестр невозможно по соображениям корпоративной безопасности, а целевой веб-сервер категорически отвергает любые соединения, кроме TLS 1.2/1.3. В таком случае самым стабильным архитектурным решением является использование бесплатной кроссплатформенной утилиты шифрования stunnel.
Принцип работы stunnel заключается в создании локального «прозрачного» туннеля:
stunnel устанавливается на компьютере (или сервере), где работает 1С, и запускается в качестве фоновой службы.stunnel.conf настраивается локальный порт, который принимает обычные незашифрованные HTTP-запросы, шифрует их по современному стандарту TLS и перенаправляет на защищенный внешний сервер.Посмотрим на пример простейшей конфигурации stunnel.conf:
[my-secure-api]
client = yes
accept = 127.0.0.1:8080
connect = mysite.com:443
verifyChain = no
При такой схеме в коде 1С вам вообще не придется заботиться о протоколах шифрования SSL/TLS, сертификатах и сложных настройках COM-объектов. Вы просто отправляете обычный HTTP-запрос на локальный адрес: http://127.0.0.1:8080. Утилита stunnel мгновенно подхватывает его, оборачивает в безопасный TLS-пакет и отправляет на оригинальный адрес https://mysite.com.
Использование туннелирования полностью решает проблемы совместимости старого программного обеспечения с высокими требованиями безопасности современных веб-серверов.