Поделиться через


Протоколы обмена сообщениями

Стек каналов Windows Communication Foundation (WCF) использует шифрование и транспортные каналы для преобразования внутренних представлений сообщений в формат для передачи по линиям связи и отправки этих сообщений с помощью определенного транспорта. Для взаимодействия веб-служб чаще всего используется транспорт HTTP, а в качестве кодировок в веб-службах чаще всего используются основанные на XML протоколы SOAP 1.1, SOAP 1.2 и механизм оптимизации передачи сообщений (MTOM).

В данном разделе приводятся сведения по реализации в WCF перечисленных ниже протоколов, используемых в HttpTransportBindingElement.

Спецификация/документ Ссылка

HTTP 1.1

http://www.ietf.org/rfc/rfc2616.txt

Привязка SOAP 1.1 HTTP

http://www.w3.org/TR/2000/NOTE-SOAP-20000508/, раздел 7

Привязка SOAP 1.2 HTTP

http://www.w3.org/TR/soap12-part2/, раздел 7

В данном разделе приводятся сведения по реализации в WCF перечисленных ниже протоколов, используемых в TextMessageEncodingBindingElement и MtomMessageEncodingBindingElement.

Спецификация/документ Ссылка

XML

http://www.w3.org/TR/REC-xml

SOAP 1.1

http://www.w3.org/TR/2000/NOTE-SOAP-20000508/

SOAP 1.2 Core

http://www.w3.org/TR/soap12-part1/

WS-Addressing 2004/08

http://www.w3.org/Submission/2004/SUBM-ws-addressing-20040810/

W3C Web Services Addressing 1.0 — Core

http://www.w3.org/TR/2006/REC-ws-addr-core-20060509

W3C Web Services Addressing 1.0 — привязка SOAP

http://www.w3.org/TR/2006/REC-ws-addr-soap-20060509

W3C Web Services Addressing 1.0 — привязка WSDL

http://www.w3.org/TR/2006/CR-ws-addr-wsdl-20060529/

W3C Web Services Addressing 1.0 — метаданные

http://www.w3.org/TR/ws-addr-metadata/

Привязка WSDL SOAP1.1

http://www.w3.org/TR/wsdl/

Привязка WSDL SOAP1.2

http://www.w3.org/Submission/wsdl11soap12/

В данном разделе приводятся сведения по реализации в WCF перечисленных ниже протоколов, используемых в MtomMessageEncodingBindingElement.

Спецификация/документ Ссылка

XOP

http://www.w3.org/TR/xop10/

MTOM + привязка SOAP 1.2

http://www.w3.org/TR/soap12-mtom/

Привязка MTOM SOAP 1.1

http://www.w3.org/Submission/soap11mtom10/

MTOM WS-Policy Assertion

http://www.w3.org/Submission/2006/SUBM-WS-MTOMPolicy-20061101/.

Во всем данном разделе используются следующие пространства имен XML и связанные с ними префиксы.

Префикс Универсальный код ресурса (URI) пространства имен

s11

https://schemas.xmlsoap.org/soap/envelope

s12

http://www.w3.org/2003/05/soap-envelope

wsa

http://www.w3.org/2004/08/addressing

wsam

http://www.w3.org/2007/05/addressing/metadata

wsap

https://schemas.xmlsoap.org/ws/2004/09/policy/addressing

wsa10

http://www.w3.org/2005/08/addressing

wsaw10

http://www.w3.org/2006/05/addressing/wsdl

xop

http://www.w3.org/2004/08/xop/include

xmime

http://www.w3.org/2004/06/xmlmime

http://www.w3.org/2005/05/xmlmime

cdp

https://schemas.microsoft.com/net/2006/06/duplex

SOAP 1.1 и SOAP 1.2

Конверт и модель обработки

В WCF реализована обработка конверта SOAP 1.1 в соответствии с профилями Basic Profile 1.1 (BP11) и Basic Profile 1.0 (SSBP10). Обработка конверта SOAP 1.2 реализована в соответствии со спецификацией SOAP12-Part1.

В этом разделе рассматриваются некоторые варианты реализации, выбранные в WCF в отношении спецификаций BP11 и SOAP12-Part1.

Обработка обязательных заголовков

WCF следует правилам по обработке заголовков, помеченных как mustUnderstand, описанным в спецификациях SOAP 1.1 и SOAP 1.2, со следующими вариациями.

Сообщение, которое поступает в стек каналов WCF, обрабатывается отдельными каналами, настроенными с помощью связанных элементов привязки, таких как кодирование текстовых сообщений, безопасность, надежный обмен сообщениями и транзакции. Каждый канал распознает заголовки из связанного пространства имен и помечает их как распознанные. После поступления сообщения в диспетчер модуль форматирования операций считывает заголовки, ожидаемые соответствующим контрактом сообщения/операции, и помечает их как распознанные. Затем диспетчер проверяет, не остались ли нераспознанные заголовки, помеченные как mustUnderstand, и создает исключение. Сообщения, содержащие заголовки mustUnderstand и предназначенные получателю, не обрабатываются кодом приложения получателя.

Такая многоуровневая обработка обеспечивает разделение уровней инфраструктуры и уровней приложения узла SOAP:

  • B1111: нераспознанные заголовки обнаруживаются после обработки стеком каналов инфраструктуры WCF, но до обработки приложением.

    Значения заголовка mustUnderstand в SOAP 1.1 и SOAP 1.2 различаются. Профиль Basic Profile 1.1 требует, чтобы для сообщений SOAP 1.1 значение параметра mustUnderstand было равно 0 или 1. В спецификации SOAP 1.2 допускаются значения 0, 1, false и true, но рекомендуется использовать каноническое представление значений xs:boolean (false, true).

  • B1112: WCF выдает для параметра mustUnderstand значения 0 и 1 в обеих версиях конвертов SOAP: SOAP 1.1 и SOAP 1.2. WCF воспринимает полное пространство значений xs:boolean для заголовка mustUnderstand (0, 1, false, true)

Ошибки SOAP

Ниже приведен список специфичных для WCF реализаций ошибок SOAP.

  • B2121: WCF возвращает следующие коды ошибок SOAP 1.1: s11:mustUnderstand, s11:Client и s11:Server.

  • B2122: WCF возвращает следующие коды ошибок SOAP 1.2: s12:MustUnderstand, s12:Sender и s12:Receiver.

Привязка HTTP

Привязка SOAP 1.1 HTTP

WCF реализует привязку SOAP1.1 HTTP в соответствии с разделом 3.4 спецификации Basic Profile 1.1 со следующими уточнениями:

  • B2211: служба WCF не реализует перенаправление запросов HTTP POST.

  • B2212: клиенты WCF поддерживают файлы cookie HTTP в соответствии с 3.4.8.

Привязка SOAP 1.2 HTTP

WCF реализует привязку SOAP 1.2 HTTP в соответствии со спецификацией SOAP 1.2-part 2 (SOAP12Part2) со следующими уточнениями.

В SOAP 1.2 введен необязательный параметр действия для типа носителя application/soap+xml. Этот параметр полезен для оптимизации распределения сообщений без необходимости анализа тела сообщения SOAP, если не используется протокол WS-Addressing.

  • R2221: параметр действия application/soap+xml, если он присутствует в запросе SOAP 1.2, должен соответствовать атрибуту soapAction элемента wsoap12:operation в соответствующей привязке WSDL.

  • R2222: параметр действия application/soap+xml, если он присутствует в сообщении SOAP 1.2, должен соответствовать wsa:Action, если используется WS-Addressing 2004/08 или WS-Addressing 1.0.

Если привязка WS-Addressing отключена, а входящий запрос не содержит параметра действия, параметр Action сообщения считается неуказанным.

WS-Addressing

В WCF реализованы 3 версии привязки WS-Addressing.

  • WS-Addressing 2004/08

  • W3C Web Services Addressing 1.0 Core (ADDR10-CORE) и SOAP Binding (ADDR10-SOAP)

  • WS-Addressing 1.0 ― метаданные

Ссылки на конечные точки

Во всех версиях WS-Addressing, реализованных в WCF, для описания конечных точек используются ссылки на конечные точки.

Ссылки на конечные точки и версии WS-Addressing

В WCF реализован ряд протоколов инфраструктуры, использующих WS-Addressing и, в частности, элемент EndpointReference и класс W3C.WsAddressing.EndpointReferenceType (например, WS-ReliableMessaging, WS-SecureConversation и WS-Trust). WCF поддерживает использование обеих версий WS-Addressing с другими протоколами инфраструктуры. Конечные точки WCF поддерживают только одну версию WS-Addressing в каждой конечной точке.

Для R3111 пространство имен элемента EndpointReference или тип, используемый в сообщениях при обмене данными с конечной точкой WCF, должен соответствовать версии WS-Addressing, реализованной в данной конечной точке.

Например, если в конечной точке WCF реализован протокол WS-ReliableMessaging, заголовок AcksTo, возвращаемый такой конечной точкой в CreateSequenceResponse, использует версию WS-Addressing, заданную элементом EncodingBinding для этой конечной точки.

Ссылки на конечные точки и метаданные

В ряде сценариев требуется передача метаданных или ссылки на метаданные для определенной конечной точки.

B3121: в WCF используются механизмы, описанные в разделе 6 спецификации WS-MetadataExchange (MEX) и позволяющие включать метаданные для ссылок на конечную точку по значению или по ссылке.

Рассмотрим сценарий, в котором служба WCF требует проверку подлинности с использованием маркера SAML (Security Assertions Markup Language), выданного издателем маркера по адресу http://sts.fabrikam123.com. Конечная точка WCF описывает это требование проверки подлинности с помощью утверждения sp:IssuedToken с вложенным утверждением sp:Issuer, указывающим на издателя маркера. Клиентское приложение, обращающееся к утверждению sp:Issuer, должно знать, как взаимодействовать с конечной точкой издателя маркера. Клиенту требуются метаданные об издателе маркера. Используя ссылку на конечную точку расширения эталонных метаданных, определенную в MEX, WCF предоставляет ссылку на метаданные издателя маркера.

<sp:IssuedToken>
  <sp:Issuer>
    <wsa10:Address>
      http://sts.fabrikam123.com
    </wsa10:Address>
    <wsa10:Metadata>
      <mex:Metadata>
        <mex:MetadataSection>
          <mex:MetadataReference>
            <wsa10:Address>
              http://sts.fabrikam123.com/mex
            </wsa10:Address>
          </mex:MetadataReference>
        </mex:MetadataSection>
      </mex:Metadata>
    </wsa10:Metadata>
  </sp:Issuer>
</sp:IssuedToken>

Заголовки адресации сообщения

Заголовки сообщения

Для всех версий WS-Addressing WCF использует следующие заголовки сообщения, указанные в спецификациях wsa:To, wsa:ReplyTo, wsa:Action, wsa:MessageID, и wsa:RelatesTo.

B3211: для всех версий WS-Addressing в WCF учитываются, но не выдаются готовые заголовки сообщения WS-Addressing — wsa:FaultTo и wsa:From.

Приложения, взаимодействующие с приложениями WCF, могут добавлять эти заголовки сообщения, и WCF обработает их соответствующим образом.

Параметры и свойства ссылок

WCF реализует обработку параметров ссылок на конечную точку и свойств

ссылок согласно соответствующим спецификациями.

B3221: если задано использование WS-Addressing 2004/08, конечные точки WCF не различают обработку свойств ссылок и параметров ссылок.

Шаблоны обмена сообщениями

Последовательность сообщений, участвующих в вызове операции веб-службы, называется шаблоном обмена сообщениями. WCF поддерживает односторонний обмен, запрос-ответ и дуплексный обмен сообщениями. В этом разделе поясняются требования WS-Addressing по обработке сообщений в зависимости от используемого шаблона обмена сообщениями.

В этом разделе первое сообщение отправляется запрашивающей стороной и принимается отвечающей стороной.

Односторонний обмен сообщениями

Если конечная точка WCF настроена на поддержку сообщений с определенным параметром Action в соответствии с односторонним обменом, конечная точка WCF следует указанным ниже поведениям и требованиям. Если не указано иное, поведения и правила применимы для обеих версий WS-Addressing, поддерживаемых в WCF.

  • R3311: запрашивающая сторона должна включить wsa:To, wsa:Action и заголовки для всех ссылочных параметров, указанных ссылкой на конечную точку. Если используется WS-Addressing 2004/08 и ссылкой на конечную точку заданы [reference properties], в сообщение также должны быть включены соответствующие заголовки.

  • B3312: запрашивающая сторона может включить заголовки MessageID, ReplyTo и FaultTo. Инфраструктура принимающей стороны не учитывает их, и они передаются в приложение.

  • R3313: если используется HTTP и по ответному плечу HTTP не передается никакое сообщение, отвечающая сторона должна отправить ответ HTTP с пустым телом и кодом состояния HTTP 202.

    Если используется транспорт HTTP и в контракте операции объявлен односторонний обмен сообщениями, ответ HTTP все равно может использоваться для отправки инфраструктурных сообщений — например, протокол надежного обмена сообщениями может отправить сообщение SequenceAcknowledgement в ответе HTTP.

  • B3314: отвечающая сторона WCF не отправляет сообщение об ошибке в ответ на одностороннее сообщение.

Запрос-ответ

Если конечная точка WCF настроена таким образом, чтобы сообщения с определенным параметром Action следовали шаблону запрос-ответ, конечная точка WCF следует указанным ниже поведениям и требованиям. Если не указано иное, поведения и правила применимы для обеих версий WS-Addressing, поддерживаемых в WCF.

  • R3321: запрашивающая сторона должна включить в запрос wsa:To, wsa:Action, wsa:MessageID и заголовки для всех [reference parameters] или [reference properties] (или и того, и другого), указанных ссылкой на конечную точку.

  • R3322: если используется WS-Addressing 2004/08, в запрос также должен быть включен параметр ReplyTo.

  • R3323: если используется WS-Addressing 1.0 и в запросе отсутствует параметр ReplyTo, используется ссылка на конечную точку по умолчанию со значением свойства [address], равным «http://www.w3.org/2005/08/addressing/anonymous».

  • R3324: запрашивающая сторона должна включить в ответное сообщение заголовки wsa:To, wsa:Action и wsa:RelatesTo, а также заголовки для всех [reference parameters] или [reference properties] (или и того, и другого), заданные в запросе ссылкой ReplyTo на конечную точку.

Ошибки Web Services Addressing

R3411: WCF создает следующие ошибки, определенные в WS-Addressing 2004/08.

Код Причина

wsa:DestinationUnreachable

Поступило сообщение со значением ReplyTo, отличающимся от адреса ответа, установленного для данного канала; нет конечной точки, ожидающей передачи данных по адресу, указанному в заголовке «To».

wsa:ActionNotSupported

Каналы инфраструктуры или диспетчер, связанные с конечной точкой, не распознали действие, указанное в заголовке Action.

R3412: WCF создает следующие ошибки, определенные в WS-Addressing 1.0.

Код Причина

wsa10:InvalidAddressingHeader

Повторяющийся wsa:To, wsa:ReplyTo, wsa:From или wsa:MessageID. Повторяющийся wsa:RelatesTo с тем же RelationshipType.

wsa10:MessageAddressingHeaderRequired

Отсутствует обязательный заголовок адресации.

wsa10:DestinationUnreachable

Поступило сообщение со значением ReplyTo, отличающимся от адреса ответа, установленного для данного канала. Нет конечной точки, ожидающей передачи данных по адресу, указанному в заголовке «To».

wsa10:ActionNotSupported

Действие, указанное в заголовке Action, не распознано каналами инфраструктуры или диспетчером, связанным с конечной точкой.

wsa10:EndpointUnavailable

Канал надежного обмена сообщениями возвращает эту ошибку, указывающую на то, что конечная точка не обрабатывает последовательность на основании проверки заголовков адресов в сообщении CreateSequence.

Код в предыдущих таблицах соответствует параметру FaultCode в SOAP 1.1 и параметру SubCode (с Code=Sender) в SOAP 1.2.

Привязка WSDL 1.1 и утверждения WS-Policy

Указание использования WS-Addressing

В WCF для указания определенной версии WS-Addressing, поддерживаемой конечной точкой, используются утверждения политики.

Следующее утверждение политики имеет субъект политики конечной точки [WS-PA] и указывает, что в сообщениях, отправляемых и принимаемых с конечной точки, должна использоваться спецификация WS-Addressing 2004/08.

<wsap:UsingAddressing />

Это утверждение политики дополняет спецификацию WS-Addressing 2004/08.

Следующее утверждение политики указывает, что в отправляемых и принимаемых сообщениях должна использоваться спецификация WS-Addressing 1.0.

<wsam:Addressing/> 

Следующее утверждение политики имеет субъект политики конечной точки [WS-PA] и указывает, что в сообщениях, отправляемых и принимаемых с конечной точки, должна использоваться спецификация WS-Addressing 2004/08.

<wsaw10:UsingAddressing />

Элемент wsaw10:UsingAddressing заимствован из [WS-Addressing-WSDL] и используется в контексте WS-Policy в соответствии с этой спецификацией, раздел 3.1.2.

Использование Addressing не изменяет семантики привязок WSDL 1.1, SOAP 1.1 и SOAP 1.2 HTTP. Например, если ожидается ответ на запрос, отправленный в конечную точку, использующую Addressing и привязку WSDL SOAP 1.x HTTP, ответ должен быть отправлен с помощью HTTP-ответа.

Для ответов, передаваемых с помощью HTTP-ответа, используется следующее утверждение WS-AM.

<wsam:AnonymousResponses/>

Полный код утверждения политики может выглядеть следующим образом.

<wsam:Addressing>
    <wsp:Policy>
        <wsam:AnonymousResponses /> 
    </wsp:Policy>
</wsam:Addressing>

Тем не менее при использовании некоторых схем обмена сообщениями удобно использовать два независимых HTTP-соединения, установленные между запрашивающей и отвечающей сторонами. Например, это позволяет принимать незапрошенные односторонние сообщения, отправленные отвечающей стороной.

WCF предоставляет возможность формирования на основе двух транспортных каналов составного дуплексного канала, в котором один канал используется для входящих сообщений, а другой — для исходящих. В случае транспорта HTTP составной дуплексный канал обеспечивает два встречных HTTP-подключения. Запрашивающая сторона использует одно соединение для отправки сообщений отвечающей стороне, а отвечающая сторона использует другой канал для отправки сообщений обратно запрашивающей стороне.

Для ответов на отдельные запросы http используется следующее утверждение WS-AM.

<wsam:NonAnonymousResponses/>

Полный код утверждения политики может выглядеть следующим образом.

<wsam:Addressing>
    <wsp:Policy>
      <wsam:NonAnonymousResponses /> 
   </wsp:Policy>
  </wsam:Addressing>

Использование следующего утверждения, содержащего субъект политики конечной точки [WS-PA], в конечных точках, в которых используются привязки WSDL 1.1 SOAP 1.x HTTP, требует двух отдельных встречных HTTP-соединений для передачи сообщений от запрашивающей стороны к отвечающей стороне и для передачи сообщений от отвечающей стороны к запрашивающей стороне соответственно.

<cdp:CompositeDuplex/>

Предыдущий оператор определяет следующие требования к заголовку wsa:ReplyTo для сообщений запроса.

  • R3514: сообщения запроса, отправляемые на конечную точку, должны содержать заголовок ReplyTo со свойством [address], не равным «http://www.w3.org/2005/08/addressing/anonymous», если эта конечная точка использует привязку WSDL 1.1 SOAP 1.x HTTP и вариант политики с утверждением wsap10:UsingAddressing или wsap:UsingAddressing и присоединенным утверждением cdp:CompositeDuplex.

  • R3515: сообщения запроса, отправляемые на конечную точку, должны содержать заголовок ReplyTo со значением свойства [address], равным «http://www.w3.org/2005/08/addressing/anonymous», или вообще не содержать заголовка ReplyTo, если эта конечная точка использует привязку WSDL 1.1 SOAP 1.x HTTP и вариант политики с утверждением wsap10:UsingAddressing без присоединенного утверждения cdp:CompositeDuplex.

  • R3516: сообщения запроса, отправляемые на конечную точку, должны содержать заголовок ReplyTo со значением свойства [address], равным «http://www.w3.org/2005/08/addressing/anonymous», если эта конечная точка использует привязку WSDL 1.1 SOAP 1.x HTTP и вариант политики с утверждением wsap:UsingAddressing без присоединенного утверждения cdp:CompositeDuplex.

Спецификация WS-Addressing языка WSDL пытается описать аналогичные привязки протокола путем введения элемента <wsaw:Anonymous/>wsa:ReplyTo с тремя текстовыми значениями (обязательный, необязательный и запрещен), указывающими требования к заголовку (раздел 3.2). К сожалению, такое определение элемента плохо подходит в качестве утверждения в контексте спецификации WS-Policy, так как оно требует специфичных для домена расширений, поддерживающих пересечение альтернатив, использующих такой элемент в качестве утверждения. Кроме того, такое определение элемента задает значение заголовка ReplyTo в противоположность поведению конечной точки в канале связи, что делает его специфичным для транспорта HTTP.

Определение действия

Спецификация WS-Addressing 2004/08 определяет атрибут wsa:Action для элементов wsdl:portType/wsdl:operation/[wsdl:input | wsdl:output | wsdl:fault]. Привязка WS-Addressing 1.0 WSDL (WS-ADDR10-WSDL) определяет аналогичный атрибут, wsaw10:Action.

Единственное отличие между этими двумя атрибутами заключается в семантике шаблона действия по умолчанию, описанной в разделе 3.3.2 спецификации WS-ADDR и в разделе 4.4.4 спецификации WS-ADDR10-WSDL соответственно.

Разумно иметь две конечные точки, использующих одинаковый тип portType (или контракт, в терминологии WCF), но различные версии спецификации WS-Addressing. Однако с учетом того, что действие определяется параметром portType и не должно изменяться между конечными точками, реализующими portType, одновременная поддержка обоих шаблонов действия по умолчанию становится невозможной.

Чтобы устранить это противоречие, WCF поддерживает одну версию атрибута Action.

B3521: независимо от версии WS-Addressing, используемой конечной точкой, для задания универсального кода ресурса (URI) действия Action для соответствующих сообщений WCF использует в элементах wsdl:portType/wsdl:operation/[wsdl:input | wsdl:output | wsdl:fault] атрибут wsaw10:Action, определенный в спецификации WS-ADDR10-WSDL.

Использование ссылки на конечную точку внутри порта WSDL

Спецификация WS-ADDR10-WSDL, раздел 4.1, расширяет элемент wsdl:port за счет дочернего элемента <wsa10:EndpointReference…/> WCF, описывающего конечную точку в терминах WS-Addressing. <wsa:EndpointReference…/> расширяет это служебное средство на спецификацию WS-Addressing 2004/08, допуская появление элемента wsdl:port в качестве дочернего для элемента.

  • R3531: если к конечной точке прикреплена альтернативная политика с утверждением политики <wsaw10:UsingAddressing/>wsdl:port, соответствующий элемент <wsa10:EndpointReference …/> может содержать дочерний элемент .

  • R3532: если элемент wsdl:port содержит дочерний элемент <wsa10:EndpointReference …/>wsa10:EndpointReference/wsa10:Address, значение дочернего элемента @address должно соответствовать значению атрибута wsdl:port элемента wsdl:location/ того же уровня.

  • R3533: если к конечной точке прикреплена альтернативная политика с утверждением политики <wsap:UsingAddressing/>wsdl:port, соответствующий элемент <wsa:EndpointReference …/> может содержать дочерний элемент .

  • R3534: если элемент wsdl:port содержит дочерний элемент <wsa:EndpointReference …/>wsa:EndpointReference/wsa:Address, значение дочернего элемента @address должно соответствовать значению атрибута wsdl:port элемента wsdl:location/ того же уровня.

Сочетаемость с WS-Security

В соответствии с разделами спецификаций WS-ADDR и WS-ADDR10, посвященными вопросам безопасности, все заголовки адресации сообщения рекомендуется подписывать совместно с телом сообщения, чтобы связать их вместе.

Если для защиты целостности сообщения используется WS-Security, заголовки сообщения WS-Addressing, а также заголовки, связанные с параметрами или свойствами (или и тем, и другим) ссылки, должны быть подписаны совместно с телом сообщения.

Примеры

Односторонний обмен сообщениями

В этом сценарии отправитель отправляет одностороннее сообщение принимающей стороне. Используются SOAP 1.2, HTTP 1.1 и W3C WS-Addressing 1.0.

Структура сообщения запроса: заголовки сообщения содержат элементы wsa10:To и wsa10:Action. Тело сообщения содержит специфичный элемент <app:Ping> из пространства имен приложения.

Заголовки HTTP: назначение в POST соответствует универсальному коду ресурса (URI) в элементе wsa10:To .

Заголовок Content-Type имеет значение application/soap+xml, как требуется спецификацией SOAP 1.2. Присутствуют параметры charset и action. Параметр action заголовка Content-Type соответствует значению заголовка сообщения wsa10:Action.

POST http://fabrikam123.com/Service HTTP/1.1
Content-Type: application/soap+xml; charset=utf-8;  
              action="http://fabrikam123.com/Service/OneWay"
Host: 131.107.72.15
Content-Length: 1501
Expect: 100-continue
Proxy-Connection: Keep-Alive
<s12:Envelope>
  <s12:Header>
    <wsa10:To s12:mustUnderstand="1">
        http://fabrikam123.com/Service
    </wsa10:To>
    <wsa10:Action s12:mustUnderstand="1">
        http://fabrikam123.com/Service/OneWay 
    </wsa10:Action>
  </s12:Header>
  <s12:Body>
    <Ping xmlns="http://fabrikam123.com/Service/">
      <Text>Hello World</Text>
    </Ping>
  </s12:Body>
</s12:Envelope>

Получающая сторона отвечает пустым ответом HTTP и состоянием 202. Пример ответа HTTP:

HTTP/1.1 202 Accepted
Date: Fri, 15 Jul 2005 08:56:07 GMT
Server: Microsoft-IIS/6.0
MicrosoftOfficeWebServer: 5.0_Pub
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50215
Cache-Control: private
Content-Length: 0

Механизм оптимизации передачи сообщений SOAP

В этом разделе приводятся сведения о реализации в WCF механизма HTTP SOAP MTOM. Технология MTOM представляет собой механизм кодирования сообщений SOAP того же класса, что и традиционная текстовая кодировка/кодировка XML или двоичная кодировка WCF. MTOM включает в себя следующие компоненты.

  • Кодировка XML и механизм упаковки, описываемый [XOP], который оптимизирует информационные элементы XML, содержащие двоичные данные в кодировке base64, в отдельные двоичные части.

  • Инкапсуляция MIME пакета XOP, которая сериализует набор сведений XML и каждую двоичную часть пакета XOP в отдельную часть MIME.

  • Кодирование MIME XOP, примененное к конверту SOAP 1.x.

  • Привязка транспорта HTTP.

WCF позволяет использовать механизм MTOM и с другими транспортами, отличными от HTTP. Однако этот раздел посвящен HTTP.

Формат MTOM построен на основе большого количества спецификаций, охватывающих сам механизм MTOM, XOP и MIME. Модульность этого набора спецификаций затрудняет реконструкцию точных требований к формату и семантике обработки. В этом разделе описываются формат и требования к обработке для привязки MTOM HTTP.

Кодирование сообщений MTOM

Создание сообщений MTOM

В спецификации [XOP], раздел 3.1, описывается процесс кодирования XML с информационными единицами элемента, содержащими base64-значения, в абстрактно определенный пакет XOP.

Приведенная ниже последовательность этапов описывает специфичный для MTOM процесс кодирования.

  1. Убедитесь, что конверт SOAP, предназначенный для кодирования, не содержит информационной единицы элемента с [namespace name], равным «http://www.w3.org/2004/08/xop/include», и [local name], равным Include.

  2. Создайте пустой пакет MIME.

  3. Определите в исходном наборе сведений XML информационные единицы элементов, подлежащие оптимизации. В оптимизируемых единицах символы, составляющие [children] информационной единицы элемента, должны быть в канонической форме xs:base64Binary (см. XSD-2, 3.2.16 base64Binary) и не должны содержать каких-либо пробельных символов перед, внутри или после непробельного содержимого.

  4. Создайте конверт XOP SOAP, являющийся копией исходного конверта SOAP, но в котором дочерние элементы всех информационных единиц элементов, определенных на предыдущем шаге, заменены информационной единицей элементов xop:Include, построенной следующим образом:

    1. Преобразуйте замененные символы в двоичные данные, обработав их как данные в кодировке base64.

    2. Создайте уникальное значение заголовка Content-ID, удовлетворяющее требованиям R3133 и R3134.

    3. Создайте заголовок Content-Transfer-Encoding MIME со значением binary.

    4. Если оптимизируемая информационная единица элемента ([parent] вновь вставленной информационной единицы xop:Include) имеет информационную единицу атрибута xmime:contentType, создайте заголовок Content-Type MIME со значением атрибута xmime:contentType.

    5. Создайте новую двоичную часть MIME с содержимым, образованным двоичными данными, декодированными из замененных символов, обработанных как base64, заголовка Content-ID из шага 4b, заголовка Content-Transfer-Encoding из шага 4c, заголовка Content-Type, если он создан в шаге 4d.

    6. Добавьте атрибут href в элемент xop:Include со значением cid: uri, полученным из значения заголовка Content-ID, созданного на шаге 4b. Удалите наружные символы «<» и «>», преобразуйте оставшуюся строку URL-адреса с использованием escape-символов, затем добавьте префикс cid:. В соответствии с RFC1738 и RFC2396 в escape-последовательности должен преобразовываться указанный ниже минимальный набор символов. Возможно преобразование в escape-символы и других символов.

      Hexadecimal 00-1F , 7F, 20, "<" | ">" | "#" | "%" | <">
      "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`" | "~" | "^"
      
  5. Создайте корневую часть MIME с конвертом XOP SOAP из шага 4.

  6. Запишите заголовки HTTP, включая заголовок HTTP Content-Type.

  7. Запишите пакет MIME.

Обработка сообщений MTOM

Обработка сообщения MTOM производится точно в обратном порядке по сравнению с процессом, описанном в предыдущем разделе «Создание сообщений MTOM».

  1. Убедитесь, что корневая часть MIME имеет Content-Type application/xop+xml.

  2. Постройте конверт SOAP, проанализировав корневую часть MIME пакета как документ XML. Кодировка символов определяется параметром charset заголовка Content-Type корневой части MIME.

  3. Для каждой информационной единицы элементов в построенном конверте SOAP, которая имеет, как единственный член своего свойства [children], информационную единицу элемента xop:Include:

    1. Удалите префикс cid: и выполните обратное преобразование из escape-представления всех escape-последовательностей универсального кода ресурса (URI) (RFC 2396) в значении атрибута @href : элемента xop:Include. Заключите получившуюся строку в «<», «>».

    2. Найдите часть MIME в значении заголовка Content-ID, соответствующую строке, полученной на шаге 3a.

    3. Замените информационную единицу элемента xop:Include, имеющуюся в свойстве children каждой единицы, информационными единицами символов, представляющими каноническую кодировку base64 (см. XSD-2, 3.2.16 base64Binary) тела сущности части MIME, указанной в шаге 3b (эффективно это означает, что надо заменить информационную единицу элемента xop:Include данными, восстановленными из части пакета).

Заголовок HTTP Content-Type

Ниже приведен список уточнений WCF для формата заголовка HTTP Content-Type сообщения SOAP 1.x с кодировкой MTOM, полученных на основе требований, указанных в самой спецификации MTOM и извлеченных из спецификаций MTOM и RFC 2387.

  • R4131: заголовок HTTP Content-Type должен иметь значение multipart/related (без учета регистра) с параметрами. В именах параметров регистр не учитывается. Порядок параметров не имеет значения.

  • Полная форма Бэкуса-Наура (BNF) заголовка Content-Type для сообщений MIME указана в RFC 2045, раздел 5.1.

  • R4132: заголовок HTTP Content-Type должен иметь параметр type со значением application/xop+xml, заключенным в двойные кавычки.

Хотя требование использовать двойные кавычки в явном виде в RFC 2387 отсутствует, в тексте отмечается, что все параметры типа носителя multipart/related весьма вероятно будут содержать зарезервированные символы, такие как "@" и "/", и, следовательно, должны быть заключены в двойные кавычки.

  • R4133: заголовок HTTP Content-Type должен иметь параметр start со значением заголовка Content-ID части MIME, содержащей конверт SOAP 1.x, заключенным в двойные кавычки. Если параметр start опущен, первая часть MIME должна содержать конверт SOAP 1.x.

  • R4134: заголовок HTTP Content-Type для сообщения с кодировкой SOAP 1.1 MTOM должен содержать параметр start-info со значением text/xml, заключенным в двойные кавычки.

  • R4135: заголовок HTTP Content-Type для сообщения с кодировкой SOAP 1.2 MTOM должен содержать параметр start-info со значением application/soap+xml, заключенным в двойные кавычки.

  • R4136: заголовок HTTP Content-Type для сообщения с кодировкой SOAP 1.x MTOM должен содержать параметр boundary со значением (заключенным в двойные кавычки), соответствующим границе MIME BNF, определенной в спецификации RFC 2046, раздел 5.1.1.

    boundary := 0*69<bchars> bcharsnospace 
    bchars := bcharsnospace / " " 
    bcharsnospace :=    DIGIT / ALPHA / "'" / "(" / ")" / "+" 
                        / "_" / "," / "-" / "." / "/" / ":" / "=" / "?"
    

    Примеры:

    ПРАВИЛЬНО

    Content-Type: multipart/related; type="application/xop+xml";start=" <part0@tempuri.org>";boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1";start-info="text/xml" 
    

    ПРАВИЛЬНО

    Content-Type: Multipart/Related; type="application/xop+xml";start-info="text/xml";boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1"
    
    

    НЕПРАВИЛЬНО

    Content-Type: Multipart/Related; type=application/xop+xml;start=" <part0@tempuri.org>";start-info="text/xml";boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1" 
    

Часть Infoset MIME

Конверт SOAP 1.x инкапсулируется как корневая часть пакета XOP MIME и часто называется частью infoset.

  • R4141: конверт SOAP 1.x должен быть инкапсулирован как корневая часть пакета XOP MIME, называемая частью infoset, ссылка на которую содержится в заголовке HTTP Content-Type.

  • R4142: часть SOAP Infoset должна содержать следующие заголовки MIME: Content-ID, Content-Transfer-Encoding и Content-Type.

Формат заголовка Content-ID определяется в RFC 2045 как

"Content-ID" ":" msg-id

где msg-id определяется в RFC 2822 (которая заменяет RFC 822, указанную в RFC 2045) следующим образом:

msg-id    =       [CFWS] "<" id-left "@" id-right ">" [CFWS]

и фактически представляет собой адрес электронной почты, заключенный в «<» и «>». Префикс и суффикс [CFWS] были добавлены в RFC 2822 для внесения комментариев и не должны использоваться, чтобы не нарушать совместимость.

R4143: значение заголовка Content-ID для части Infoset MIME должно задаваться в соответствии с правилами для msg-id из RFC 2822 без частей с префиксом и суффиксом [CFWS].

В ряде реализаций MIME ослаблены требования к тому, чтобы значение внутри «<» и «>» было адресом электронной почты, и, помимо адреса электронной почты, допускается использование absoluteURI в угловых скобках «<» и «>». В этой версии WCF используются значения заголовка Content-ID MIME в виде:

Content-ID: <http://tempuri.org/0> 

R4144: процессоры MTOM должны воспринимать значения заголовка Content-ID, соответствующие следующему ослабленному требованию к msg-id.

msg-id-relaxed =     [CFWS] "<" (absoluteURI | mail-address) ">" [CFWS]
mail-address   =     id-left "@" id-right

В MIME (RFC 2045) предусмотрен заголовок Content-Transfer-Encoding для сообщения о кодировке содержимого части MIME. По умолчанию для Content-Transfer-Encoding задано значение 7-bit, которое не подходит для большинства сообщений SOAP, поэтому для расширения совместимости требуется заголовок Content-Transfer-Encoding:

  • R4145: часть SOAP Infoset должна содержать заголовок Content-Transfer-Encoding.

  • R4146: если для конверта SOAP принята кодировка символов UTF-8, значение заголовка Content-Transfer-Encoding должно быть 8-bit.

  • R4147: если для конверта SOAP принята кодировка символов UTF-16, значение заголовка Content-Transfer-Encoding должно быть binary.

  • В соответствии с [XOP], раздел 5,

  • R4148: часть SOAP1.1 Infoset должна содержать заголовок Content-Type с типом носителя application/xop+xml и параметрами type="text/xml" и charset

    Content-Type: application/xop+xml;
                  charset=utf-8;type="text/xml"
    
  • R4149: часть SOAP 1.2 Infoset должна содержать заголовок Content-Type с типом носителя application/xop+xml и параметрами type="application/soap+xml" и charset.

    Content-Type: application/xop+xml;
                  charset=utf-8;type="application/soap+xml"
    

    Хотя в XOP параметр charset для application/xop+xml определяется как необязательный, он необходим для совместимости, аналогично требованию BP 1.1 к параметру charset для типа носителя text/xml.

  • R41410: в заголовке Content-Type части SOAP 1.x Infoset должны присутствовать параметры type и charset.

Поддержка MTOM конечной точкой WCF

Целью механизма MTOM является кодирование сообщения SOAP для оптимизации данных с кодировкой base64. Ниже приведен список ограничений.

  • R4151: любая информационная единица элемента, содержащая данные в кодировке base64, может быть оптимизирована.

  • B4152: WCF оптимизирует информационные единицы элементов, содержащие данные в кодировке base64 с длиной более 1024 байта.

Конечная точка WCF, настроенная для использования механизма MTOM, будет всегда передавать сообщения с кодировкой MTOM. Даже если ни одна из частей не удовлетворяет требуемым критериям, сообщение все равно является MTOM-кодированным (сериализованным в виде пакета MIME с единственной частью MIME, содержащей конверт SOAP).

Утверждение WS-Policy для MTOM

В WCF для указания того, что в конечной точке применяется механизм MTOM, используется приведенное ниже утверждение политики.

<wsoma:OptimizedMimeSerialization ... />
  • R4211: предыдущее утверждение политики содержит субъект политики конечной точки и указывает, что все сообщения, отправляемые на конечную точку и получаемые от нее, должны быть оптимизированы с помощью MTOM.

  • B4212: если в конечной точке WCF задана оптимизация MTOM, конечная точка добавляет утверждение политики MTOM в политику, присоединенную к соответствующей привязке wsdl:binding.

Сочетаемость с WS-Security

MTOM представляет собой механизм кодирования, аналогичный text/xml и WCF Binary XML. MTOM обеспечивает естественную сочетаемость с протоколом WS-Security и другими протоколами WS-*: сообщение, защищенное с помощью протокола WS-Security, может быть оптимизировано с помощью MTOM.

Примеры

Сообщение WCF SOAP 1.1, закодированное с помощью MTOM

POST http://131.107.72.15/Mtom/svc/service.svc/Soap11MtomUTF8 HTTP/1.1
SOAPAction: "http://xmlsoap.org/echoBinaryAsString"
Content-Type: multipart/related;type="application/xop+xml";
              start="<http://tempuri.org/0>";start-info="text/xml";
       boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1"
Host: 131.107.72.15
Content-Length: 1501
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1
Content-ID: <http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <EchoBinaryAsString xmlns="http://xmlsoap.org/Ping">
      <array>
        <xop:Include 
         href="cid:http%3A%2F%2Ftempuri.org%2F1%2F632618206521093670" 
         xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
      </array>
    </EchoBinaryAsString>
  </s:Body>
</s:Envelope>
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1
Content-ID: <http://tempuri.org/1/632618206521093670>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream
…Binary Content..
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=1

Безопасное сообщение WCF SOAP 1.2, закодированное с помощью MTOM

В этом примере с помощью MTOM и SOAP 1.2 кодируется сообщение, защищенное с помощью протокола WS-Security. Двоичные части, указанные для кодирования, являются содержимым элементов BinarySecurityToken, CipherValue элемента EncryptedData, соответствующих зашифрованной подписи и зашифрованному телу. Обратите внимание, что элемент CipherValue элемента EncryptedKey не указан для оптимизации в WCF, так как его длина меньше 1024 байт.

POST http://131.107.72.15/Mtom/service.svc/Soap12MtomSecureSignEncrypt HTTP/1.1
Content-Type: multipart/related; type="application/xop+xml";
              start="<http://tempuri.org/0>";
            boundary="uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3";
              start-info="application/soap+xml"; 
              action="http://xmlsoap.org/echoBinaryAsString"
Host: 131.107.72.15
Content-Length: 1941
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3
Content-ID: <http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="application/soap+xml"
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <s:Header>
    <o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
      <u:Timestamp u:Id="uuid-4d4ee765-5717-4d53-9ac9-99bddc07df6c-5">
        <u:Created>2005-09-09T06:57:32.488Z</u:Created>
        <u:Expires>2005-09-09T07:02:32.488Z</u:Expires>
      </u:Timestamp>
      <o:BinarySecurityToken u:Id="uuid-4d4ee765-5717-4d53-9ac9-99bddc07df6c-2" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">
        <xop:Include href="cid:http%3A%2F%2Ftempuri.org%2F1%2F632618206525089430" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
      </o:BinarySecurityToken>
      <e:EncryptedKey Id="_1" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
        <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <o:SecurityTokenReference>
            <o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier">Xeg55vRyK3ZhAEhEf+YT0z986L0=</o:KeyIdentifier>
          </o:SecurityTokenReference>
        </KeyInfo>
        <e:CipherData>          <e:CipherValue>oQfpxwT8/SAGyZQzKE2b4yO6dXuQj7pwJ+5CGL3Rf7C06bQ5ttMoQ9GLJcQYkXTzin+WwHEgs5bj5ml9HKTW9QAU5JJ6lksdymmQvWP5ZtGPBVchO4sofEGoCKmBiZL/DYS/cnbzgnc/3a6NYnc10y2fWGaGLiqa00zijAw7o0Y=</e:CipherValue>
        </e:CipherData>
      </e:EncryptedKey>
      <c:DerivedKeyToken u:Id="_2" xmlns:c="https://schemas.xmlsoap.org/ws/2005/02/sc">
        <o:SecurityTokenReference>
          <o:Reference URI="#_1"/>
        </o:SecurityTokenReference>
        <c:Nonce>OrEPRX7fISIS4sXYWPMv3g==</c:Nonce>
      </c:DerivedKeyToken>
      <e:ReferenceList xmlns:e="http://www.w3.org/2001/04/xmlenc#">
        <e:DataReference URI="#_3"/>
        <e:DataReference URI="#_4"/>
      </e:ReferenceList>
      <e:EncryptedData Id="_4" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
        <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
          <o:SecurityTokenReference>
            <o:Reference URI="#_2"/>
          </o:SecurityTokenReference>
        </KeyInfo>
        <e:CipherData>
          <e:CipherValue>
            <xop:Include href="cid:http%3A%2F%2Ftempuri.org%2F2%2F632618206525089430" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
          </e:CipherValue>
        </e:CipherData>
      </e:EncryptedData>
    </o:Security>
  </s:Header>
  <s:Body u:Id="_0">
    <e:EncryptedData Id="_3" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
      <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
      <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
        <o:SecurityTokenReference xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
          <o:Reference URI="#_2"/>
        </o:SecurityTokenReference>
      </KeyInfo>
      <e:CipherData>
        <e:CipherValue>
          <xop:Include href="cid:http%3A%2F%2Ftempuri.org%2F3%2F632618206525089430" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
        </e:CipherValue>
      </e:CipherData>
    </e:EncryptedData>
  </s:Body>
</s:Envelope>
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3
Content-ID: <http://tempuri.org/1/632618206525089430>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream
...Binary content of BinarySecurityToken - X509 Certificate...
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3
Content-ID: <http://tempuri.org/2/632618206525089430>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream
...Binary serialization of the encrypted primary signature...
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3
Content-ID: <http://tempuri.org/3/632618206525089430>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream
...Binary serialization of the encrypted Body...
--uuid:0ca0e16e-feb1-426c-97d8-c4508ada5e82+id=3--