Что такое SOAP?
SOAP (Simple Object Access Protocol) это протокол для общения через язык разметки XML используя HTT. Хотя SOAP может работать поверх различных транспортных протоколов, наиболее распространённым вариантом является использование HTTP или HTTPS, что делает его удобным для веб-служб. Благодаря использованию XML, SOAP обеспечивает строгую структуру данных и поддержку сложных операций. Этот протокол широко применяется в корпоративных системах, где важны безопасность, надежность и строгие стандарты обмена информацией.
В этой статье мы рассмотрим, как SOAP функционирует в связке с HTTP/HTTPS.
Что такое WSDL?
WSDL (Web Services Description Language) — это XML-схема, которая описывает, как правильно строить XML-сообщения для взаимодействия с SOAP-сервисом. WSDL определяет протокол для обмена сообщениями, структуру самих сообщений, доступные операции и возможные ответы на них.
С помощью WSDL клиент может понять, как взаимодействовать с веб-сервисом, какие данные отправлять и какие ответы ожидать. Это упрощает интеграцию различных систем, поскольку предоставляет четкие инструкции по взаимодействию через SOAP.
Где находится WSDL схема?
Необходимо иметь доступ к API. Например, api калькулятора - http://www.dneonline.com/calculator.asmx.
Благодаря своей простоте тот API отлично подходит для практики и отправки первый запроса через SOAP. Для того чтобы найти WSDL-схему, нужно просто добавить ?wsdl
в конец URL, как показано здесь: http://www.dneonline.com/calculator.asmx?wsdl
Защищённость SOAP
Почему оно безопасно?
SOAP считается безопасным протоколом благодаря строгим стандартам, которые требуют создания XML-документов строго по описанным правилам схемы. Это позволяет заранее знать структуру получаемых данных и определить возможные ответы как в случае успешных, так и в случае неудачных запросов.
Кроме того, большинство SOAP-схем требуют, чтобы запросы подписывались в соответствии с установленными стандартами безопасности, а также предусматривалось их шифрование. Это помогает решать важные вопросы, такие как целостность данных, предотвращение повторного воспроизведения запросов, подмену сообщений и другие угрозы безопасности.
Пример http запроса, использующий SOAP:
POST /WebService.asmx HTTP/1.1
Host: www.example.com
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://example.com/GetInfo"
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemasxmlsoap.org/soap/envelope/">
<soap:Body>
<GetInfo xmlns="http://example.com/">
<param1>value1</param1>
<param2>value2</param2>
</GetInfo>
</soap:Body>
</soap:Envelope>
Наше xml-soap-сообщение помещается в тело http-сообщения, и мы также получаем аналогичные http-запросы.
Из чего состоит SOAP-сообщение
xml
Каждое SOAP-сообщение начинается с объявления стандарта, который указывает, какую версию XML используется в сообщении. Разные API могут требовать различные версии XML, поэтому важно уточнять серверу, какую версию XML мы используем при построении запроса. Это помогает избежать ошибок и обеспечить корректное взаимодействие между клиентом и сервером.
<?xml version="1.0" encoding="utf-8"?>
Envelope
Каждое SOAP-сообщение должно начинаться с элемента
Некоторые из распространённых неймспейсов, таких как xmlns:xsi
, xmlns:xsd
и xmlns:soap
, стандартизируют сообщение и позволяют его получателю понять, по каким правилам оно построено. Неймспейсы обеспечивают правильную интерпретацию данных и помогают избежать конфликтов в именах элементов.
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" # xmls
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemasxmlsoap.org/soap/envelope/">
</soap:Envelope>
Header
Элемент Header
в SOAP-сообщении является необязательным и предназначен для хранения метаданных, таких как информация о аутентификации, адресе назначения и другие данные, которые могут быть полезны при обработке сообщения.
В некоторых случаях элемент Header
может быть пустым. Однако он также может содержать неймспейсы, параметры и другие структуры, аналогичные тем, что находятся в теле сообщения Body
. Таким образом, Header
предоставляет дополнительную гибкость в обмене данными и может использоваться для различных нужд, не влияя на содержимое основного сообщения.
# there is empty Header without any data
<soapenv:Header/>
# there is authentication data for accesssing message
<soapenv:Header>
<ex:Security> # were dont defined "ex" namespace, its just an example.
<ex:UsernameToken>
<ex:Username>john_doe</ex:Username>
<ex:Password>securePassword123</ex:Password>
</ex:UsernameToken>
</ex:Security>
</soapenv:Header>
Body
Тело SOAP-сообщения Body
хранит сам запрос к конкретному ресурсу или методу, а также параметры, которые необходимы для выполнения этого запроса. Это могут быть различные фильтры, параметры для создания ресурсов и другие данные, которые требуются для взаимодействия с сервером.
В случае с калькулятором, например, мы обращаемся к методу (таким как “прибавить”, “отнять”, “умножить” или “разделить”) и передаем два параметра, на которых будет выполнена операция. Таким образом, тело сообщения содержит все необходимые данные для выполнения запроса.
GetInfo
- Это метод к которому мы обращаемся;param1
иparam 2
- Это передаваемые параметры внутри метода;
<soap:Body>
<GetInfo xmlns="http://example.com/">
<param1>value1</param1>
<param2>value2</param2>
</GetInfo>
</soap:Body>
Ответ SOAP сообщения
Ответ от SOAP-сервера также представляет собой XML-документ, имеющий похожую структуру, включающую элементы Envelope
и Body
. Эти элементы содержат информацию о результате запроса, аналогично тому, как они используются в исходном сообщении.
Однако в некоторых случаях, когда происходит ошибка в процессе обработки запроса, может быть добавлен дополнительный элемент — Fault
. Этот элемент сообщает об ошибках, возникших на стороне сервера, и содержит подробности о характере проблемы, что помогает клиенту понять, что пошло не так.
Fault
Элемент Fault
в SOAP-сообщении — это необязательный элемент, который используется для отображения информации об ошибках, возникших во время обработки запроса. Этот элемент появляется, когда отправленное сообщение построено неправильно или содержит ошибки, например, некорректные данные или проблемы с синтаксисом.
Когда сервер обнаруживает ошибку в сообщении, он может включить элемент Fault
в ответ, чтобы предоставить подробности о проблеме. Это помогает клиенту быстро идентифицировать и устранить ошибки в запросе.
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Client</faultcode>
<faultstring>Invalid parameters</faultstring>
<faultactor>http://example.com/service</faultactor>
<detail>
<errorCode>1</errorCode>
<errorMessage>Provided param1 is not valid in the system.</errorMessage>
</detail>
</soapenv:Fault>
</soapenv:Body>
Ws-Security
WS-Security — это стандарт, который обеспечивает механизмы безопасности для веб-сервисов, включая SOAP. Он гарантирует, что сообщение не будет изменено во время передачи, обеспечивая целостность данных. Этот стандарт также включает методы аутентификации, шифрования и цифровой подписи, что делает обмен данными более безопасным. WS-Security помогает защитить веб-сервисы от различных угроз, таких как подмена сообщений и несанкционированный доступ.
<soapenv:Header>
<wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/07/secext">
<wsse:UsernameToken>
<wsse:Username>testUser</wsse:Username>
<wsse:Password>testPassword</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
Как работать с SOAP и производить его отладку (debug)?
Для работы с SOAP существует множество инструментов, но я рекомендую SoapUI. Это невероятно удобный инструмент, который позволяет легко генерировать XML-документы и отправлять запросы. По сути, это такой же инструмент, как Postman, но специально предназначенный для работы с XML и SOAP.
SoapUI используется многими компаниями для тестирования своих SOAP-API. С помощью него можно легко экспортировать схемы и в один клик импортировать их в инструмент, получив доступ ко всем методам, параметрам, а также примерам запросов и ответов. Это значительно упрощает процесс отладки и взаимодействия с SOAP-сервисами.
SOAP on Ruby
Многие разработчики предпочитают строить XML-документы вручную — это один из самых простых способов отправки запросов через SOAP. В таком случае часто создаётся монолитный объектно-ориентированный класс, который возвращает строку с XML-документом. Это хороший и быстрый способ, но важно подумать о поддержке такого кода в будущем.
В нашем примере мы не будем создавать сложный ООП-класс. Вместо этого SOAP-сообщение представлено просто строкой, что позволяет легко и быстро отправить запрос без излишней сложности.
require 'net/http'
require 'uri'
soap_message = <<~XML
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://example.com/">
<soapenv:Header/>
<soapenv:Body>
<web:GetData>
<web:Parameter>SampleValue</web:Parameter>
</web:GetData>
</soapenv:Body>
</soapenv:Envelope>
XML
url = URI.parse("http://example.com/soap-endpoint")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Post.new(url.path, { 'Content-Type' => 'text/xml; charset=utf-8' })
request.body = soap_message
response = http.request(request)
puts response.body
Полезные ruby gems
В Ruby есть несколько гемов, которые пригодятся для решения проблем:
Savon - Тяжелый металлический SOAP-клиент, который генерирует xml и отправляет запросы на ruby
У рубина существует множество инструментов для работы с SOAP. Самый популярный из них savon
require 'savon'
# Initialize the client with the WSDL URL of the SOAP service
client = Savon.client(wsdl: 'http://www.dneonline.com/calculator.asmx?WSDL')
# Make a request to the 'Add' operation of the service
response = client.call(:add, message: { 'intA' => 5, 'intB' => 3 })
response.body
Гем, используя схему wsdl, создает xml документ по заданным правилам. Фактически сгенерированный xml будет иметь вид:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:web="http://www.dneonline.com/webservice/">
<soapenv:Header/>
<soapenv:Body>
<web:Add>
<web:intA>5</web:intA>
<web:intB>3</web:intB>
</web:Add>
</soapenv:Body>
</soapenv:Envelope>
XMLDSig: цифровая подпись для XML-документов
XMLDSig (XML Digital Signature) — это стандарт для подписания XML-документов, который обеспечивает их подлинность, целостность и невозможность отказа от подписи. Основная цель XMLDSig — позволить подписывать как весь XML-документ, так и его отдельные части, предоставляя доказательства того, что документ не был изменён после подписания.
Подписание документа вручную может быть достаточно сложным процессом, но для упрощения задачи существует гем XMLDSig, который значительно облегчает эту работу.
Однако есть и плохие новости — данный гем больше не поддерживается его создателями. Тем не менее, он по-прежнему работает на новых версиях Ruby, и, например, в моём проекте он успешно используется с Ruby 3.3.0.
Конец
SOAP — это мощный и гибкий протокол для обмена сообщениями, который, благодаря строгим стандартам и механизму безопасности, является надёжным выбором для веб-сервисов, где важна целостность данных и защита от несанкционированного доступа.