При интеграции систем на платформе 1С:Предприятие часто возникает задача использования современных стандартов безопасности, таких как JWT (JSON Web Token). Если с HTTPСервисами работа через заголовок Authorization: Bearer не вызывает сложностей, то при использовании Web-сервисов (SOAP) и стандартного объекта WSПрокси разработчики сталкиваются с серьезным ограничением: этот объект не предоставляет прямого доступа к HTTP-заголовкам запроса. Разберем подробно, почему так происходит, и какими способами можно решить эту задачу.
Объект WSПрокси в платформе 1С является высокоуровневой оберткой. Он предназначен для того, чтобы разработчик мог вызывать методы удаленного сервиса так же просто, как методы локального объекта, не заботясь о формировании XML-пакета SOAP. Однако эта абстракция скрывает низкоуровневую работу с протоколом HTTP. В отличие от объекта HTTPЗапрос, у WSПрокси нет коллекции Заголовки. Попытки программно внедрить заголовок в HTTPСоединение, которое якобы используется внутри прокси (как показано в некоторых ошибочных примерах кода), не увенчаются успехом, так как платформа не предоставляет доступа к внутреннему транспортному уровню WSПрокси.
Рассмотрим доступные пути решения этой задачи, начиная от настройки инфраструктуры и заканчивая изменением программного подхода.
Это наиболее правильный "платформенный" метод. Начиная с версии 8.3.15, в 1С реализована поддержка внешней аутентификации. Мы можем настроить информационную базу так, чтобы она принимала токены автоматически. Проанализируем необходимые действия:
default.vrd на веб-сервере.<point>) необходимо добавить параметры для работы с внешними токенами.identifiableByExternalToken="true".При такой настройке платформа сама будет искать токен в заголовке Authorization или в параметрах URL. Если токен валиден и соответствует пользователю, сессия будет установлена автоматически. Это позволяет использовать стандартный WSПрокси на стороне клиента, при условии, что механизм передачи токена настроен на уровне взаимодействия между серверами.
Если мы не можем изменить заголовки, платформа предлагает альтернативный канал передачи токена — через параметры строки запроса. Для этого при создании WSПрокси мы можем модифицировать URL местоположения сервиса. Выясним, как это реализовать на практике:
В строке соединения к веб-сервису необходимо добавить параметр AccessToken. Важно помнить, что токен должен быть передан в формате Base64URL. Рассмотрим пример логики формирования строки:
// Пример формирования адреса с токеном
ТокенJWT = "ваш_токен_в_формате_base64url";
АдресСервиса = "https://server.com/base/ws/Service?AccessToken=" + ТокенJWT;
// При создании прокси используем модифицированный адрес
WSОпределения = Новый WSОпределения(АдресСервиса + "&wsdl", Логин, Пароль);
WSПрокси = Новый WSПрокси(WSОпределения, "http://www.uri.com", "ServiceName", "ServiceSoap");
Важное ограничение: передача токена в URL считается менее безопасной, чем в заголовках, так как параметры запроса могут логироваться веб-серверами (Apache/IIS). Используйте этот метод только через защищенное соединение HTTPS.
Если первые два метода не подходят (например, из-за жестких требований безопасности или ограничений конкретной версии платформы), мы можем отказаться от использования WSПрокси в пользу HTTPЗапрос. Многие разработчики опасаются этого метода из-за необходимости "вручную" собирать XML-текст SOAP-конверта, но мы применим более элегантный подход с использованием ФабрикаXDTO.
Разберем этот процесс по шагам:
WSОпределения для доступа к структуре данных сервиса.ФабрикаXDTO создаем объект, соответствующий входному параметру метода веб-сервиса.HTTPСоединение, где мы можем свободно добавить заголовок Authorization: Bearer.Проанализируем пример кода для реализации этой схемы:
// 1. Готовим данные через XDTO
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
// Здесь мы формируем структуру SOAP-конверта с помощью Фабрики
// Для упрощения показан принцип записи объекта данных
ФабрикаXDTO.ЗаписатьXML(ЗаписьXML, ОбъектПараметровМетода, "RequestName", "http://namespace.uri");
ТелоЗапроса = ЗаписьXML.Закрыть();
// 2. Формируем HTTP-запрос
HTTPСоединение = Новый HTTPСоединение("ваш_сервер", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос("/base/ws/service.1cws");
Запрос.Заголовки.Вставить("Authorization", "Bearer " + JWTТокен);
Запрос.Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
Запрос.УстановитьТелоИзСтроки(ТелоЗапроса);
// 3. Отправляем и обрабатываем результат
Ответ = HTTPСоединение.ОтправитьДляОбъекта(Запрос);
Если Ответ.КодСостояния = 200 Тогда
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
РезультатXDTO = ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
КонецЕсли;
Этот метод дает нам полный контроль над процессом. Мы сохраняем типизацию данных благодаря ФабрикаXDTO, но при этом получаем гибкость HTTPЗапроса для работы с JWT.
Подведем итоги нашего анализа. Выбор метода зависит от архитектуры вашего решения:
Во-первых, если вы контролируете обе стороны интеграции (и клиентскую, и серверную базу 1С), лучше всего настроить default.vrd и использовать стандартный WSПрокси. Это потребует минимум изменений в коде 1С.
Во-вторых, если вам нужно быстрое решение "здесь и сейчас" и политика безопасности допускает использование параметров URL, используйте AccessToken.
В-третьих, для максимально гибких и защищенных интеграций, особенно при взаимодействии со сторонними (не 1С) сервисами, мы рекомендуем использовать связку HTTPЗапрос + ФабрикаXDTO. Это исключит зависимость от специфического поведения объекта WSПрокси и позволит в точности соблюсти требования протокола JWT.
Помните, что при работе с JWT важно следить за сроком жизни токена (exp) и своевременно выполнять его обновление (refresh token), что также удобнее реализовывать через механизмы HTTPЗапрос.