Protocolos de mensagens

A pilha de canais do Windows Communication Foundation (WCF) emprega canais de codificação e transporte para transformar a representação de mensagem interna em seu formato de transmissão e enviá-la usando um transporte específico. O transporte mais comum usado para interoperabilidade de serviços Web é HTTP e as codificações mais comuns usadas pelos serviços Web são SOAP 1.1, SOAP 1.2 baseado em XML e MTOM (Mecanismo de Otimização de Transmissão de Mensagens).

Este tópico aborda os detalhes da implementação do WCF para os seguintes protocolos empregados por HttpTransportBindingElement.

Especificação/Documento:

Este tópico aborda os detalhes da implementação do WCF para os seguintes protocolos empregados por TextMessageEncodingBindingElement e MtomMessageEncodingBindingElement.

Especificação/Documento:

Este tópico aborda os detalhes da implementação do WCF para os seguintes protocolos empregados por MtomMessageEncodingBindingElement.

Especificação/Documento:

Os seguintes namespaces XML e prefixos associados são usados ao longo deste tópico:

Prefixo URI (Uniform Resource Identifier) do namespace
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 e SOAP 1.2

Envelope e modelo de processamento

O WCF implementa o processamento de envelope SOAP 1.1 seguindo o Perfil Básico 1.1 (BP11) e o Perfil Básico 1.0 (SSBP10). O processamento de envelope SOAP 1.2 é implementado após SOAP12-Part1.

Esta seção explica determinadas opções de implementação feitas pelo WCF em relação a BP11 e SOAP12-Part1.

Processamento de cabeçalho obrigatório

O WCF segue as regras para processamento de cabeçalhos marcados com mustUnderstand descritos nas especificações SOAP 1.1 e SOAP 1.2, com as seguintes variações.

Uma mensagem que insere a pilha de canais do WCF é processada por canais individuais configurados por elementos de associação relacionados, por exemplo, Codificação de mensagem de texto, Segurança, Mensagens confiáveis e Transações. Cada canal reconhece cabeçalhos do namespace associado e os marca conforme entendido. Depois que uma mensagem entra no dispatcher, o formatador de operação lê os cabeçalhos esperados pelo contrato de operação/mensagem correspondente e marca como entendido. Em seguida, o dispatcher verifica se os cabeçalhos restantes não são entendidos, mas marcados como mustUnderstand e gera uma exceção. As mensagens que contêm cabeçalhos mustUnderstand direcionados ao destinatário não são processadas pelo código do aplicativo do destinatário.

Esse processamento em camadas permite a separação entre camadas de infraestrutura e camadas de aplicativo do nó SOAP:

  • B1111: cabeçalhos que não entendidos são detectados depois que a mensagem é processada pela pilha de canais de infraestrutura do WCF, mas antes de ser processada pelo aplicativo

    O valor do cabeçalho mustUnderstand é diferente entre SOAP 1.1 e SOAP 1.2. O Basic Profile 1.1 requer que o valor mustUnderstand seja 0 ou 1 para mensagens SOAP 1.1. O SOAP 1.2 permite 0, 1, false e true como valores, mas recomenda emitir uma representação canônica de valores xs:boolean (false, true).

  • B1112: o WCF emite valores mustUnderstand 0 e 1 para as versões SOAP 1.1 e SOAP 1.2 do envelope SOAP. O WCF aceita todo o espaço de valor do xs:boolean para cabeçalho mustUnderstand (0, 1, false, true)

Falha de SOAP

Veja a seguir uma lista de implementações de falha SOAP específicas do WCF.

  • B2121: o WCF retorna os seguintes códigos de falha SOAP 1.1: s11:mustUnderstand, s11:Client e s11:Server.

  • B2122: o WCF retorna os seguintes códigos de falha SOAP 1.2: s12:MustUnderstand, s12:Sender e s12:Receiver.

Associação HTTP

SOAP 1.1 HTTP Binding

O WCF implementa a SOAP1.1 HTTP binding de acordo com a especificação de Basic Profile 1.1 seção 3.4 com os seguintes esclarecimentos:

  • B2211: o serviço WCF não implementa o redirecionamento de solicitações HTTP POST.

  • B2212: os clientes do WCF suportam Cookies HTTP de acordo com 3.4.8.

SOAP 1.2 HTTP Binding

O WCF implementa o SOAP 1.2 HTTP binding, conforme descrito na especificação SOAP 1.2-part 2 (SOAP12Part2) com os seguintes esclarecimentos.

SOAP 1.2 introduziu um parâmetro de ação opcional para o tipo de mídia application/soap+xml. Esse parâmetro é útil para otimizar a expedição de mensagens sem exigir que o corpo da mensagem SOAP seja analisado quando WS-Addressing não for usado.

  • R2221: o parâmetro de ação application/soap+xml, quando presente em uma solicitação SOAP 1.2, deve corresponder ao atributo soapAction no elemento wsoap12:operation dentro da associação WSDL correspondente.

  • R2222: o parâmetro de ação application/soap+xml, quando presente em uma mensagem SOAP 1.2, deve corresponder wsa:Action quando WS-Addressing 2004/08 ou WS-Addressing 1.0 são usados.

Quando WS-Addressing está desabilitado e uma solicitação de entrada não contiver um parâmetro de ação, a mensagem Action não é considerada especificada.

WS-Addressing

O WCF implementa três versões do WS-Addressing:

  • WS-Addressing 2004/08

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

  • WS-Addressing 1.0 - Metadata

Referências de ponto de extremidade

Todas as versões de WS-Addressing usadas pelo WCF usam referências de ponto de extremidade para descrever pontos de extremidade.

Referências de ponto de extremidade e versões de WS-Addressing

O WCF implementa vários protocolos de infraestrutura que usam WS-Addressing e, em particular, o elemento EndpointReference e classe W3C.WsAddressing.EndpointReferenceType (por exemplo, WS-ReliableMessaging, WS-SecureConversation e WS-Trust). O WCF dá suporte ao uso de qualquer versão do WS-Addressing com outros protocolos de infraestrutura. Os pontos de extremidade do WCF suportam uma versão de WS-Addressing por ponto de extremidade.

Para R3111, o namespace para o elemento EndpointReference ou tipo usado em mensagens trocadas com um ponto de extremidade WCF deve corresponder à versão de WS-Addressing implementada por esse ponto de extremidade.

Por exemplo, se um ponto de extremidade do WCF implementar o WS-ReliableMessaging, o cabeçalhoAcksTo retornado por esse ponto de extremidade dentro de CreateSequenceResponse usa a versão WS-Addressing especificada pelo elemento EncodingBinding para esse ponto de extremidade.

Referências e metadados do ponto de extremidade

Diversos cenários exigem a comunicação de metadados ou uma referência a metadados para um determinado ponto de extremidade.

B3121: O WCF emprega mecanismos descritos na especificação de WS-MetadataExchange (MEX) Seção 6 para incluir metadados para referências de ponto de extremidade por valor ou por referência.

Considere um cenário em que um serviço WCF requer autenticação usando um token SAML (Security Assertions Markup Language) emitido pelo emissor do token em http://sts.fabrikam123.com. O ponto de extremidade do WCF descreve esse requisito de autenticação usando uma declaração sp:IssuedToken com uma declaração aninhada sp:Issuer direcionada ao emissor do token. Os aplicativos do cliente que acessam a declaração sp:Issuer precisam saber como se comunicar com o ponto de extremidade do emissor do token. O cliente precisa conhecer os metadados sobre o emissor do token. Usando as extensões de metadados de referência do ponto de extremidade definidas no MEX, o WCF fornece uma referência aos metadados do emissor do token.

<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>

Cabeçalhos de Endereçamento de Mensagens

Cabeçalhos da mensagem

Para ambas as versões WS-Addressing, o WCF usa os cabeçalhos de mensagem a seguir conforme prescrito pelas especificaçõeswsa:To, wsa:ReplyTo, wsa:Action, wsa:MessageID e wsa:RelatesTo.

B3211: para todas as versões WS-Addressing, o WCF atende, mas não está pronto, cabeçalhos de mensagens WS-Addressing de wsa:FaultTo e wsa:From.

Os aplicativos que interagem com aplicativos do WCF podem adicionar esses cabeçalhos de mensagem e o WCF processará adequadamente.

Propriedades e Parâmetros de Referência

O WCF implementa o processamento de parâmetros de referência de ponto de extremidade e propriedades de referência de acordo com as respectivas especificações.

B3221: quando configurado para usar WS-Addressing 2004/08, os pontos de extremidade do WCF não diferenciam entre o processamento de propriedades de referência e parâmetros de referência.

Padrões de troca de mensagens

A sequência de mensagens envolvidas na chamada da operação de serviço Web é conhecida como padrão de troca de mensagens. O WCF suporta padrões de troca de mensagens solicitação-resposta, unidirecional e duplex. Esta seção mostra os requisitos para WS-Addressing sobre o processamento de mensagens, dependendo do padrão de troca de mensagens que está sendo usado.

Ao longo desta seção, o solicitante envia a primeira mensagem e o respondente recebe a primeira mensagem.

Mensagem unidirecional

Quando um ponto de extremidade do WCF é configurado para dar suporte a mensagens com um determinado Action para seguir um padrão unidirecional, o ponto de extremidade do WCF segue os seguintes comportamentos e requisitos. A menos que especificado de outra forma, comportamentos e regras se aplicam a as duas versões de WS-Addressing com suporte no WCF:

  • R3311: o solicitante deve incluir wsa:To, wsa:Action e cabeçalhos para todos os parâmetros de referência especificados pela referência do ponto de extremidade. Quando o WS-Addressing 2004/08 é usado e as [propriedades de referência] são especificadas pela referência do ponto de extremidade, os cabeçalhos correspondentes também devem ser adicionados à mensagem.

  • B3312: o solicitante pode incluir cabeçalhos MessageID, ReplyToe FaultTo. A infraestrutura do receptor ignora os cabeçalhos e serão passados para o aplicativo.

  • R3313: quando HTTP é usado e nenhuma mensagem está sendo enviada na perna de resposta HTTP, o respondente deve enviar uma resposta HTTP com um corpo vazio e um código de status HTTP 202.

    Quando o transporte HTTP está em uso e o contrato de operação declara uma mensagem unidirecional, a resposta HTTP ainda pode ser usada para enviar mensagens de infraestrutura. Por exemplo, mensagens confiáveis podem enviar uma mensagem SequenceAcknowledgement em uma resposta HTTP.

  • B3314: o respondente do WCF não envia uma mensagem de falha em resposta a uma mensagem unidirecional.

Solicitação-resposta

Quando um ponto de extremidade do WCF é configurado para uma mensagem com um determinado Action para seguir o padrão de solicitação-resposta, o ponto de extremidade do WCF segue os comportamentos e requisitos abaixo. A menos que especificado de outra forma, comportamentos e regras se aplicam a as duas versões de WS-Addressing com suporte no WCF:

  • R3321: o solicitante deve incluir na solicitação wsa:To, wsa:Action, wsa:MessageIDe cabeçalhos para todos os parâmetros de referência ou propriedades de referência (ou os dois) especificadas pela referência do ponto de extremidade.

  • R3322: quando o WS-Addressing 2004/08 é usado, ReplyTo também deve ser incluído na solicitação.

  • R3323: quando WS-Addressing 1.0 é usado e ReplyTo não está na solicitação, uma referência de ponto de extremidade padrão com a propriedade [address] igual a http://www.w3.org/2005/08/addressing/anonymous é usada.

  • R3324: o solicitante deve incluir os cabeçalhos wsa:To, wsa:Action e wsa:RelatesTo na mensagem de resposta, bem como cabeçalhos para todos os parâmetros de referência ou propriedades de referência (ou ambos) especificados pela referência do ponto de extremidade ReplyTo na solicitação.

Falhas no Web Services Addressing

R3411: o WCF produz as seguintes falhas definidas pelo WS-Addressing 2004/08.

Código Causa
wsa:DestinationUnreachable A mensagem chegou com um ReplyTo diferente do endereço de resposta estabelecido para este canal. Não há nenhum ponto de extremidade com o endereço especificado no cabeçalho Para.
wsa:ActionNotSupported Os canais de infraestrutura ou o dispatcher associados ao ponto de extremidade não reconhecem a ação especificada no cabeçalho Action.

R3412: o WCF produz as seguintes falhas definidas pelo WS-Addressing 1.0.

Código Causa
wsa10:InvalidAddressingHeader Duplicar wsa:To, wsa:ReplyTo, wsa:From ou wsa:MessageID. Duplicar wsa:RelatesTo com o mesmo RelationshipType.
wsa10:MessageAddressingHeaderRequired O cabeçalho de endereçamento necessário está ausente.
wsa10:DestinationUnreachable A mensagem chegou com um ReplyTo diferente do endereço de resposta estabelecido para este canal. Não há nenhum ponto de extremidade com o endereço especificado no cabeçalho Para.
wsa10:ActionNotSupported Uma ação especificada no cabeçalho Action não é reconhecido pelos canais de infraestrutura ou dispatcher associado ao ponto de extremidade.
wsa10:EndpointUnavailable O canal RM envia essa falha novamente, indicando que o ponto de extremidade não processa a sequência com base na análise dos cabeçalhos de endereçamento da mensagem CreateSequence.

O código nas tabelas anteriores é mapeado para FaultCode no SOAP 1.1 e SubCode (com Código=Remetente) em SOAP 1.2.

Declarações de WS-Policy e WSDL 1.1 Binding

Indicando o uso de WS-Addressing

O WCF usa declarações de política para indicar o suporte ao ponto de extremidade para uma versão de WS-Addressing específica.

A declaração de política a seguir tem uma Política de Ponto de extremidade [WS-PA] e indica que as mensagens enviadas e recebidas do ponto de extremidade devem usar WS-Addressing 2004/08.

<wsap:UsingAddressing />

Essa declaração de política reforça a especificação WS-Addressing 2004/08.

A declaração de política a seguir indica que as mensagens enviadas/recebidas devem usar WS-Addressing 1.0.

<wsam:Addressing/>

A declaração de política a seguir tem uma Política de Ponto de Extremidade [WS-PA] e indica que as mensagens enviadas e recebidas do ponto de extremidade devem usar WS-Addressing 2004/08.

<wsaw10:UsingAddressing />

O elemento wsaw10:UsingAddressing é emprestado de [WS-Addressing-WSDL] e usado no contexto de WS-Policy em conformidade com essa especificação, seção 3.1.2.

O uso de Endereçamento não altera a semântica das associações HTTP WSDL 1.1, SOAP 1.1 e SOAP 1.2. Por exemplo, se for esperada uma resposta para uma solicitação que é enviada para um ponto de extremidade que usa Endereçamento e associação HTTP WSDL SOAP 1.x, a resposta deve ser enviada usando a resposta HTTP.

Para respostas enviadas pela resposta http, a declaração do WS-AM é:

<wsam:AnonymousResponses/>

A declaração de política completa pode ser:

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

No entanto, há padrões de troca de mensagens que se beneficiam de ter duas conexões HTTP de conversa independente estabelecidas entre o solicitante e o respondente, por exemplo, mensagens unidirecionais não solicitadas enviadas pelo respondente.

O WCF oferece um recurso pelo qual dois canais de transporte subjacentes podem formar um canal dúplex composto, onde um canal é usado para mensagens de entrada e o outro é usado para mensagens de saída. No caso do transporte HTTP, o duplex composto oferece duas conexões HTTP inversas. O solicitante usa uma conexão para enviar mensagens ao respondente e o respondente usa a outra para enviar mensagens de volta ao solicitante.

Para respostas enviadas por solicitações http separadas, a declaração ws-am é:

<wsam:NonAnonymousResponses/>

A declaração de política completa pode ser:

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

O uso da declaração a seguir que tem a Política de Ponto de Extremidade [WS-PA] em pontos de extremidade que usam associações HTTP WSDL 1.1 SOAP 1.x requer duas conexões HTTP inversas separadas a serem usadas para mensagens que fluem do solicitante para o respondente e do respondente para o solicitante, respectivamente.

<cdp:CompositeDuplex/>

A instrução anterior leva aos seguintes requisitos no cabeçalho wsa:ReplyTo para mensagens de solicitação:

  • R3514: as mensagens de solicitação enviadas para um ponto de extremidade devem ter um cabeçalho ReplyTo com a propriedade [address] que não é igual a http://www.w3.org/2005/08/addressing/anonymous se o ponto de extremidade usa uma associação HTTP SOAP WSDL 1.1 SOAP 1.x e tem uma alternativa de política com uma instrução wsap10:UsingAddressing ou wsap:UsingAddressing acoplada à cdp:CompositeDuplex anexada.

  • R3515: as mensagens de solicitação enviadas para um ponto de extremidade devem ter um cabeçalho ReplyTo com a propriedade [address] igual a http://www.w3.org/2005/08/addressing/anonymous ou não tem um cabeçalho ReplyTo, se o ponto de extremidade usa uma associação HTTP WSDL 1.1 SOAP 1.x e tem uma alternativa de política com uma instrução wsap10:UsingAddressing e nenhuma instrução cdp:CompositeDuplex anexada.

  • R3516: as mensagens de solicitação enviadas para um ponto de extremidade devem ter um cabeçalho ReplyTo com a propriedade [address] igual a http://www.w3.org/2005/08/addressing/anonymous se o ponto de extremidade usa uma associação HTTP WSDL 1.1 SOAP 1.x e tem uma alternativa de política com uma instrução wsap:UsingAddressing e nenhuma instrução cdp:CompositeDuplex anexada.

A especificação WSDL de WS-addressing tenta descrever associações de protocolo semelhantes que mostram um elemento <wsaw:Anonymous/> com três valores textuais (obrigatórios, opcionais e proibidos) para indicar requisitos no cabeçalho wsa:ReplyTo (seção 3.2). Infelizmente, essa definição de elemento não é usada principalmente como uma declaração no contexto de WS-Policy, pois requer extensões específicas de domínio para oferecer suporte à interseção de alternativas usando um elemento como uma instrução. Essa definição de elemento também indica o valor do cabeçalho ReplyTo em oposição ao comportamento do ponto de extremidade na internet, o que o torna específico para o transporte HTTP.

Definição de ação

O WS-Addressing 2004/08 define um atributo wsa:Action para os elementos wsdl:portType/wsdl:operation/[wsdl:input | wsdl:output | wsdl:fault]. A associação WSDL WS-Addressing 1.0 (WS-ADDR10-WSDL) define um atributo wsaw10:Action semelhante.

A única diferença entre os dois é a semântica padrão de ação descrita na seção 3.3.2 do WS-ADDR e na seção 4.4.4 do WS-ADDR10-WSDL, respectivamente.

É necessário ter dois pontos de extremidade que compartilham o mesmo portType (ou contrato, na terminologia do WCF), mas usando versões diferentes do WS-Addressing. Mas considerando que a ação é definida por portType e não deve mudar entre os pontos de extremidade que implementam portType, é impossível oferecer suporte aos dois padrões de ação.

Para solucionar essa controvérsia, o WCF oferecer suporte a uma única versão do atributo Action.

B3521: o WCF usa o atributo wsaw10:Action nos elementos wsdl:portType/wsdl:operation/[wsdl:input | wsdl:output | wsdl:fault] conforme definido em WS-ADDR10-WSDL para determinar o URI Action das mensagens correspondentes, independente da versão de WS-Addressing usada pelo ponto de extremidade.

Usar referência de ponto de extremidade dentro da porta WSDL

A seção 4.1 do WS-ADDR10-WSDL estende o elemento wsdl:port para incluir o elemento filho <wsa10:EndpointReference…/> para descrever o ponto de extremidade em termos de WS-Addressing. O WCF amplia esse utilitário no WS-Addressing 2004/08, o que permite que <wsa:EndpointReference…/> apareça como um elemento filho de wsdl:port.

  • R3531: se um ponto de extremidade tiver uma alternativa de política anexada com uma declaração de política <wsaw10:UsingAddressing/>, o elemento correspondente wsdl:port pode conter um elemento filho <wsa10:EndpointReference …/>.

  • R3532: se wsdl:port contém um elemento filho <wsa10:EndpointReference …/>, o valor do elemento filho wsa10:EndpointReference/wsa10:Address deve corresponder ao valor do atributo @address do elemento irmão wsdl:port/wsdl:location .

  • R3533: se um ponto de extremidade tiver uma alternativa de política anexada com uma instrução de política <wsap:UsingAddressing/>, o elemento correspondente wsdl:port pode conter um elemento filho <wsa:EndpointReference …/>.

  • R3534: se wsdl:port contém um elemento filho <wsa:EndpointReference …/>, o valor do elemento filho wsa:EndpointReference/wsa:Address deve corresponder ao valor do atributo @address do elemento irmão wsdl:port/wsdl:location.

Composição com WS-Policy

De acordo com as seções de consideração de segurança no WS-ADDR e no WS-ADDR10, é recomendável que todos os cabeçalhos de mensagem de endereçamento sejam assinados junto com o corpo da mensagem para fazer associação.

Quando o WS-Security é usado para proteção de integridade da mensagem, os cabeçalhos de mensagem do WS-Addressing, além de cabeçalhos resultantes de parâmetros de referência ou propriedades (ou ambos) devem ser assinados junto com o corpo da mensagem.

Exemplos

Mensagem unidirecional

Nesse cenário, o remetente envia uma mensagem unidirecional para o destinatário. SOAP 1.2, HTTP 1.1 e W3C WS-Addressing 1.0 são usados.

A Estrutura da Mensagem de Solicitação: os cabeçalhos de mensagem incluem elementos wsa10:To e wsa10:Action. O corpo da mensagem inclui um elemento específico <app:Ping> do namespace do aplicativo.

Cabeçalhos HTTP: o destino no POST corresponde ao URI no elemento wsa10:To.

O cabeçalho Content-Type tem o valor de application/soap+xml conforme exigido pelo SOAP 1.2. Os parâmetros charset e action estão incluídos. O parâmetro action do cabeçalho Content-Type corresponde ao valor do cabeçalho da mensagem 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>

O destinatário responde com uma resposta HTTP vazia e o status 202. Um exemplo da resposta 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

Mecanismo de Otimização da Transmissão de Mensagem SOAP

Esta seção descreve os detalhes da implementação do WCF para HTTP SOAP MTOM. A tecnologia MTOM é o mecanismo de codificação de mensagens SOAP da mesma classe que a codificação tradicional de texto/XML ou a codificação binária do WCF. MTOM inclui o seguinte:

  • Um mecanismo de codificação e empacotamento XML descrito por [XOP] que otimiza itens de informações XML contendo dados binários codificados de base64 em partes binárias separadas.

  • Um encapsulamento MIME do pacote XOP que serializa o Infoset XML e cada parte binária do pacote XOP em uma parte MIME separada.

  • Uma codificação XOP de MIME aplicada ao Envelope SOAP 1.x.

  • Uma associação de transporte HTTP.

É possível usar o MTOM com transportes não HTTP com o WCF. No entanto, neste tópico, trataremos especificamente no HTTP.

O formato MTOM aproveita um grande conjunto de especificações que incluem o próprio MTOM, XOP e MIME. O processo modular desse conjunto de especificações dificulta um pouco a reconstrução de requisitos exatos no formato e na semântica de processamento. Esta seção descreve os requisitos de formato e processamento para associação HTTP MTOM.

Codificação de mensagem MTOM

Gerando mensagens MTOM

A seção 3.1 [XOP] descreve o processo de codificação de XML com itens de informações de elemento que contêm valores base64 em um pacote XOP definido de forma abstrata.

A sequência de etapas a seguir descreve o processo de codificação específico do MTOM:

  1. Verifique se o Envelope SOAP a ser codificado não contém nenhum item de informação de elemento com um [namespace name] de http://www.w3.org/2004/08/xop/include e um [local name] de Include.

  2. Crie um pacote MIME vazio.

  3. Identifique no Infoset XML original os itens de informações do elemento a serem otimizados. Para que os itens sejam otimizados, os caracteres que compõem [children] do item de informações do elemento devem estar na forma canônica de xs:base64Binary (consulte XSD-2, 3.2.16 base64Binary) e não devem conter nenhum caractere de espaço em branco anterior, embutido ou após o conteúdo de espaço que não está em branco.

  4. Crie um Envelope SOAP XOP que seja uma cópia do Envelope SOAP Original, mas com os filhos de cada item de informação de elemento identificado na etapa anterior e substituído por um item de informação de elemento xop:Include construído da seguinte forma:

    1. Transforme os caracteres substituídos em dados binários processando como dados codificados em base64.

    2. Gere um valor de cabeçalho de ID de conteúdo exclusivo que atenda aos requisitos R3133 e R3134.

    3. Gere um cabeçalho MIME de codificação de transferência de conteúdo com o valor binário.

    4. Se o item de informações do elemento otimizado (o [pai] do item de informações do elemento xop:Include recém-inserido) tiver um item de informações de atributo xmime:contentType, gere um cabeçalho MIME Content-Type com o valor do atributo xmime:contentType.

    5. Gere uma nova parte do MIME binário com conteúdo formado por dados binários decodificados dos caracteres substituídos processados como base64, cabeçalho Content-ID de 4b, cabeçalho Content-Transfer-Encoding de 4c, cabeçalho Content-Type, se gerado na etapa 4d.

    6. Adicione um atributo href ao elemento xop:Include com o valor cid: uri derivado do valor do cabeçalho Content-ID gerado na etapa 4b. Remova os caracteres delimitadores "<" e ">", escape de URL da cadeia de caracteres restante e adicione o prefixo cid:. O conjunto de caracteres mínimo a seguir é obrigatório para o escape por RFC1738 e RFC2396. Outros caracteres podem ser escapados.

      Hexadecimal 00-1F , 7F, 20, "<" | ">" | "#" | "%" | <">
      "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`" | "~" | "^"
      
  5. Crie uma parte raiz do MIME com o Envelope SOAP XOP da etapa 4.

  6. Grave os cabeçalhos HTTP, incluindo o cabeçalho Content-Type HTTP.

  7. Grave o pacote MIME.

Processando mensagens MTOM

O processamento de uma mensagem MTOM é exatamente o inverso do processo descrito na seção anterior "Gerando mensagens MTOM":

  1. Verifique se a parte raiz do MIME tem o Content-Type application/xop+xml.

  2. Construa um Envelope SOAP analisando a parte raiz do MIME do pacote como um documento XML. A codificação de caracteres é determinada pelo parâmetro charset do Content-Type da parte raiz do MIME.

  3. Para cada item de informações de elemento no Envelope SOAP construído, que tem, como único membro de sua propriedade [filhos], um item de informações de elemento xop:Include:

    1. Remova o prefixo cid: e remova todas as sequências de escape de URI (RFC 2396) no valor do atributo @href do elemento xop:Include. Coloque a cadeia de caracteres de resultado em "<", ">".

    2. Localize a parte MIME com o valor do cabeçalho Content-ID que corresponde à cadeia de caracteres derivada na etapa 3a.

    3. Substitua o item de informações de elemento xop:Include que aparece na propriedade children de cada item pelos itens de informações de caractere que representam a codificação base64 canônica (consulte XSD-2, 3.2.16 base64Binary) do corpo da entidade da parte MIME identificada na etapa 3b (substitua efetivamente o item de informações do elemento xop:Include pelos dados reconstruídos da parte do pacote).

Cabeçalho HTTP Content-Type

Veja a seguir uma lista de esclarecimentos do WCF para o formato do cabeçalho HTTP Content-Type de uma mensagem codificada em SOAP 1.x MTOM derivada de requisitos declarados na própria especificação MTOM e derivados de MTOM e RFC 2387.

  • R4131: um cabeçalho HTTP Content-Type deve ter o valor de várias partes/relacionadas (que não diferencia maiúsculas de minúsculas) e seus parâmetros. Nomes de parâmetros diferenciam maiúsculas de minúsculas. A ordem do parâmetro não é importante.

  • O formulário completo de Backus-Naur (BNF) do cabeçalho Content-Type para mensagens MIME está listado no RFC 2045, seção 5.1.

  • R4132: um cabeçalho HTTP Content-Type deve ter um parâmetro de tipo com o valor application/xop+xml entre aspas duplas.

Embora o requisito de usar aspas duplas não seja explícito no RFC 2387, o texto mostra que todos os parâmetros de tipo de mídia de várias partes/relacionados provavelmente contêm caracteres reservados como "@" ou "/" e, portanto, precisam de aspas duplas.

  • R4133: um cabeçalho HTTP Content-Type deve ter um parâmetro de início com o valor do cabeçalho Content-ID da parte MIME que contém o Envelope SOAP 1.x, entre aspas duplas. Se o parâmetro inicial for omitido, a primeira parte MIME deve conter o Envelope SOAP 1.x.

  • R4134: um cabeçalho HTTP Content-Type para uma mensagem codificada em SOAP 1.1 MTOM deve incluir o parâmetro de informações de início com o valor de texto/xml, entre aspas duplas.

  • R4135: um cabeçalho HTTP Content-Type para uma mensagem codificada em SOAP 1.2 MTOM deve incluir o parâmetro de informações de início com o valor de application/soap+xml, entre aspas duplas.

  • R4136: cabeçalho HTTP Content-Type para uma mensagem codificada em MTOM SOAP 1.x deve ter o parâmetro de limite com o valor (entre aspas duplas) que corresponde ao limite do MIME BNF definido na RFC 2046, seção 5.1.1

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

    Exemplos:

    CORRETO

    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"
    

    CORRETO

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

    INCORRETO

    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"
    

Parte Infoset MIME

O Envelope SOAP 1.x é encapsulado como uma parte raiz do pacote MIME XOP e geralmente é chamado de parte infoset.

  • R4141: o Envelope SOAP 1.x deve ser encapsulado como uma parte raiz do pacote MIME XOP, chamado de bloco infoset e referenciado do HTTP Content-Type.

  • R4142: o bloco SOAP Infoset deve incluir os seguintes cabeçalhos MIME: Content-ID, Content-Transfer-Encoding e Content-Type.

O formato do cabeçalho Content-ID é definido pelo RFC 2045 como

"Content-ID" ":" msg-id

onde msg-id é definido no RFC 2822 (que substitui o RFC 822, referenciado no RFC 2045) como:

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

e é efetivamente um endereço de email entre "<" e ">". O prefixo e o sufixo [CFWS] foram adicionados no RFC 2822 para carregar comentários e não devem ser usados para preservar a interoperabilidade.

R4143: o valor do cabeçalho Content-ID da parte Infoset MIME deve seguir a produção msg-id do RFC 2822 com os blocos de prefixo e sufixo [CFWS] omitidos.

Várias implementações MIME flexibilizaram os requisitos para que o valor entre "<" e ">" seja um endereço de email e usado absoluteURI entre "<" e "" e ">" além do endereço de email. Esta versão do WCF usa valores do cabeçalho Content-ID MIME do formulário:

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

R4144: os processadores MTOM devem aceitar valores de cabeçalho Content-ID que correspondam ao seguinte msg-id flexibilizado.

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

O MIME (RFC 2045) fornece o cabeçalho Content-Transfer-Encoding para comunicar a codificação do conteúdo do bloco MIME. O padrão definido para Content-Transfer-Encoding é de 7 bit, o que não é adequado para a maioria das mensagens SOAP, portanto, o cabeçalho Content-Transfer-Encoding é necessário para maior interoperabilidade:

  • R4145: o bloco SOAP Infoset deve conter o cabeçalho Content-Transfer-Encoding.

  • R4146: se a codificação de caracteres do envelope SOAP for UTF-8, o valor do cabeçalho Content-Transfer-Encoding deve ser de 8 bits.

  • R4147: se a codificação de caracteres do envelope SOAP for UTF-16, o valor do cabeçalho Content-Transfer-Encoding deve ser binário.

  • De acordo com a seção 5 do [XOP],

  • R4148: parte do SOAP1.1 Infoset deve conter cabeçalho Content-Type com aplicativo de tipo de mídia/xop+xml e parâmetros type="text/xml" e conjunto de caracteres

    Content-Type: application/xop+xml;
                  charset=utf-8;type="text/xml"
    
  • R4149: o bloco do SOAP 1.2 Infoset deve conter o cabeçalho Content-Type com tipo de mídia application/xop+xml e parâmetros type="application/soap+xml" e charset.

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

    Embora o XOP defina o parâmetro charset para application/xop+xml como opcional, é necessário para a interoperabilidade semelhante ao requisito BP 1.1 no parâmetro charset para o tipo de mídia text/xml.

  • R41410: os parâmetros type e charset devem estar presentes no cabeçalho Content-Type do bloco SOAP 1.x Infoset.

Suporte ao ponto de extremidade do WCF para MTOM

A finalidade do MTOM é codificar uma mensagem SOAP para otimizar dados codificados em base64. Veja a seguir uma lista de restrições:

  • R4151: qualquer item de informação de elemento que contenha dados codificados em base64 pode ser otimizado.

  • B4152: o WCF otimiza itens de informações de elemento que contêm dados codificados em base64 e excedem 1024 bytes de comprimento.

Um ponto de extremidade WCF configurado para usar o MTOM sempre envia mensagens codificadas em MTOM. Mesmo que nenhuma parte atenda aos critérios necessários, a mensagem ainda será codificada em MTOM (serializada como um pacote MIME com uma única parte MIME que contém o envelope SOAP).

Declaração WS-Policy para MTOM

O WCF usa a seguinte declaração de política para indicar o uso de MTOM por ponto de extremidade:

<wsoma:OptimizedMimeSerialization />
  • R4211: a declaração de política anterior tem uma Política de Ponto de Extremidade e especifica que todas as mensagens enviadas e recebidas do ponto de extremidade devem ser otimizadas usando MTOM.

  • B4212: quando configurado para usar a otimização MTOM, um ponto de extremidade do WCF adiciona uma declaração de Política MTOM à política anexada à wsdl:bindingcorrespondente.

Composição com WS-Policy

O MTOM é um mecanismo de codificação semelhante ao text/xml e XML binário do WCF. O MTOM oferece composição natural com WS-Security e outros protocolos WS*: uma mensagem protegida usando WS-Security pode ser otimizada usando MTOM.

Exemplos

Mensagem SOAP 1.1 do WCF codificada usando 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

Mensagem SOAP 1.2 segura do WCF codificada usando MTOM

Neste exemplo, uma mensagem é codificada usando MTOM e SOAP 1.2 protegidos usando o WS-Security. As partes binárias identificadas para codificação são os conteúdos de BinarySecurityToken, CipherValue de EncryptedData correspondente à assinatura criptografada e ao corpo criptografado. Observe que CipherValue de EncryptedKey não foi identificado para otimização pelo WCF, pois seu comprimento é menor que 1024 bytes.

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--