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

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

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

Спецификация и документ:

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

Спецификация и документ:

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

Спецификация и документ:

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

Префикс Универсальный код ресурса (URI) пространства имен
s11 http://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 http://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
dp http://schemas.microsoft.com/net/2006/06/duplex

SOAP 1.1 и SOAP 1.2

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

WCF реализует обработку конвертов SOAP 1.1 после базового профиля 1.1 (BP11) и базового профиля 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 1.1 и SOAP 1.2 конверта SOAP. WCF принимает все пространство значений заголовка xs:booleanmustUnderstand (0, 1, , ) falsetrue

Ошибки SOAP

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

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

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

Привязка HTTP

Привязка SOAP 1.1 HTTP

WCF реализует привязку HTTP SOAP1.1 после раздела спецификации "Базовый профиль 1.1" 3.4 со следующими пояснениями:

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

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

Привязка SOAP 1,2 HTTP

WCF реализует привязку HTTP SOAP 1.2, как описано в спецификации SOAP 1.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-Адресации:

  • WS-Addressing 2004/08

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

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

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

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

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

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

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

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

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

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

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

Рассмотрим сценарий, в котором служба WCF требует проверки подлинности с помощью маркера языка разметки утверждений безопасности (SAML), выданного издателем 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-Адресации WCF использует следующие заголовки сообщений, как указано в спецификацияхwsa:To, , wsa:ReplyTo, wsa:Actionи wsa:MessageID.wsa:RelatesTo

B3211: для всех версий WS-Адресации wcF учитывается, но не производится из поля, заголовки wsa:FaultTo сообщений WS-Адресации и wsa:From.

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

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

WCF реализует обработку эталонных параметров конечной точки и ссылочных свойств в соответствии с соответствующими спецификациями.

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

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

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

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

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

Если конечная точка WCF настроена для поддержки сообщений с заданным Action шаблоном одностороннего использования, конечная точка WCF соответствует следующим поведению и требованиям. Если иное не указано, поведение и правила применяются для обеих версий WS-Адресации, поддерживаемых в 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-Адресации, поддерживаемых в WCF:

  • R3321: запрашиватель должен включать в запрос wsa:To, wsa:Actionwsa:MessageIDи заголовки для всех ссылочных параметров или ссылочных свойств (или обоих), указанных ссылкой на конечную точку.

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

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

  • R3324: запрашиватель должен включать wsa:Towsa:Actionwsa:RelatesTo и заголовки в ответном сообщении, а также заголовки для всех ссылочных параметров или ссылочных свойств (или обоих), указанных ReplyTo ссылкой на конечную точку в запросе.

Ошибки Web Services Addressing

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

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

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

Код Причина
wsa10:InvalidAddressingHeader Повторяющиесяwsa:To, wsa:Fromwsa:ReplyToили 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-Адресации.

Следующее утверждение политики имеет субъект политики конечной точки [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 и имеет альтернативу политике с 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 и имеет альтернативу политике с wsap:UsingAddressing утверждением и отсутствием cdp:CompositeDuplex утверждения.

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

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

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

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

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

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

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

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

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

Можно использовать MTOM с транспортами, отличными от HTTP, с WCF. Однако этот раздел посвящен 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, текст отмечает, что все параметры многопартийного или связанного типа мультимедиа, скорее всего, содержат зарезервированные символы, такие как "@" или "/", и поэтому требуются двойные кавычки.

  • 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 используются значения заголовка MIME Content-ID формы:

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: часть Infoset SOAP1.1 должна содержать заголовок Content-Type с приложением типа мультимедиа/xop+xml и параметрами type="text/xml" и charset

    Content-Type: application/xop+xml;
                  charset=utf-8;type="text/xml"
    
  • R4149: часть infoset SOAP 1.2 должна содержать заголовок Content-Type с типом носителя и типом application/xop+xml параметров"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: при настройке оптимизации MTOM конечная точка WCF добавляет утверждение политики MTOM к политике, подключенной к соответствующей wsdl:bindingполитике.

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

MTOM — это механизм кодирования, аналогичный text/xml xml-файлу WCF Binary. 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="http://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="http://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="http://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--