Conteúdo


Serviços da Web Java

Entendendo a WS-Policy

Aprenda os detalhes da WS-Policy e veja quais partes trabalham com três pilhas de serviços da Web Java de software livre

Comments

Conteúdos da série:

Esse conteúdo é a parte # de # na série: Serviços da Web Java

Fique ligado em conteúdos adicionais dessa série.

Esse conteúdo é parte da série:Serviços da Web Java

Fique ligado em conteúdos adicionais dessa série.

Você viu muitos exemplos da WS-Policy e WS-SecurityPolicy na série Serviços da Web Java, mas até o momento sem nenhuma discussão sobre como a WS-Policy realmente funciona (ou, pelo menos, deveria funcionar). Neste artigo, eu vou primeiro preencher as lacunas abordando um pouco mais os fundamentos da WS-Policy. Em seguida veremos como anexar políticas nos serviços nos documentos WSDL. Por fim, vou testar alguns exemplos de configuração da WS-Policy do Axis2, Metro e CXF e contar como eles trabalham na prática. (Consulte a seção Download para obter o código de amostra completo.)

Fundamentos da WS-Policy

A WS-Policy define uma estrutura XML simples que consiste em quatro elementos diferentes e um par de atributos. Esses elementos e atributos, conforme a interpretação da WS-Policy, fornecem uma forma de organizar e combinar asserções de políticas com qualquer nível de complexidade. Para definir as asserções atuais que compõe uma política, use extensões específicas do domínio como a WS-SecurityPolicy, ao invés da WS-Policy per se.

Para conveniência, a WS-Policy define uma expressão de política na forma normal e um conjunto de regras que podem ser usadas para criar expressões de políticas mais compactas. A forma normal pode ser detalhada de alguma forma, então (apesar das recomendações da WS-Policy determinando que "a forma normal de uma expressão de política DEVERÁ ser utilizada quando possível") a maioria dos autores de documentos sobre políticas tende a usar ao menos algumas seções das regras de expressão compactas para facilitar o uso dos documentos para as pessoas. A interpretação dos documentos sobre políticas é baseada na forma normal, então esse será o primeiro item abordado.

Expressão na Forma Normal

A expressão de política na forma normal usa no mínimo três elementos, que devem ser aninhados sempre em uma ordem específica. O elemento mais externo é sempre o <wsp:Policy> e ele deve conter um único elemento filho <wsp:ExactlyOne> . O <wsp:ExactlyOne> aninhado, por sua vez, contém qualquer número (possivelmente zero) de elementos filhos <wsp:All> . Então a expressão de política na forma normal mais simples é <wsp:Policy><wsp:ExactlyOne/></wsp:Policy>.

Todas as asserções de políticas na forma normal devem ser aninhadas com um elemento <wsp:All> . Essas asserções de políticas podem conter asserções de políticas. Isso foi visto nos artigos anteriores dessa série, nos quais diversas asserções da WS-SecurityPolicy continham expressões de políticas aninhadas. Em uma expressão de política na forma normal, todas essas asserções de políticas aninhadas também devem estar na forma normal. (Na verdade, elas devem estar em um subconjunto ainda mais restritivo da forma normal, onde cada elemento <wsp:ExactlyOne> com exceção do primeiro possui somente um elemento filho <wsp:All> .) A Listagem 1 mostra um extrato com diversos exemplos de expressões de políticas aninhadas, expressas na forma normal:

Listagem 1. Extrato de WS-SecurityPolicy com expressões de políticas aninhadas
                <wsp:Policy> <wsp:ExactlyOne>
                <wsp:All> <sp:AsymmetricBinding
                xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                <wsp:Policy> <wsp:ExactlyOne>
                <wsp:All> <sp:InitiatorToken>
                <wsp:Policy> <wsp:ExactlyOne>
                <wsp:All> <sp:X509Token
                sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
                <wsp:Policy> <wsp:ExactlyOne>
                <wsp:All>
                <sp:RequireThumbprintReference/>
                </wsp:All> </wsp:ExactlyOne>
                </wsp:Policy> </sp:X509Token>
                </wsp:All> </wsp:ExactlyOne>
                </wsp:Policy> </sp:InitiatorToken>
                ...

Apesar das diversas camadas de elementos aninhados, a semântica dessa estrutura é simples. Na expressão de política na forma normal, <wsp:Policy> é somente um wrapper para a expressão de política e, no caso de expressões de políticas de nível superior, um local para anexar um nome ou um identificador na política. O elemento <wsp:ExactlyOne> aninhado representa uma combinação ou das alternativas representadas pelos elementos <wsp:All> aninhados (então a expressão de política completa será verdadeira se qualquer uma das alternativas aninhadas for verdadeira). Cada elemento <wsp:All> representa uma combinação e das asserções de políticas aninhadas (então a alternativa será verdadeira somente se todas as asserções forem verdadeiras).

Política Não Normalizada

As expressões de políticas não precisam estar na forma normal. As expressões de políticas não normais podem incluir alternativas aninhadas (diversos elementos filho <wsp:All> de um elemento <wsp:ExactlyOne> abaixo do nível superior) e também podem usar as opções de expressões de políticas compactas que serão discutidas na próxima seção.

Se você estudou a teoria da lógica, talvez reconheça a representação da forma normal (sem alternativas aninhadas) como equivalente à forma normal disjuntiva de uma expressão lógica. As expressões de políticas são, na verdade, somente expressões lógicas que usam o formato dos sinais de maior e menor, com asserções como cláusulas. A teoria da lógica mostra que qualquer expressão lógica pode ser convertida para a forma normal disjuntiva e o mesmo princípio se aplica às expressões de políticas escritas com alternativas aninhadas — elas podem ser expandidas para uma forma normal de representação com alternativas somente no nível superior. A principal vantagem da expressão de política na forma normal é facilitar a verificação da compatibilidade de duas políticas através do programa — se as duas políticas na forma normal forem compatíveis, elas terão um ou mais elementos <wsp:All> de nível superior contendo os mesmos conjuntos de asserções.

Expressão de Política Compacta

A expressão de política na forma normal pode ser extensa, principalmente se incluir alternativas aninhadas. A WS-Policy define opções que podem ser usadas para criar expressões de políticas mais concisas do que o permitido na forma normal, facilitando o entendimento das políticas. A documentação da WS-Policy é confusa ao se referir algumas vezes às políticas usando essas opções como sendo na forma compacta. Na verdade, muitas expressões de políticas compactas podem ser equivalentes a uma única expressão na forma normal. Neste artigo, usarei somente expressões compactas para me referir ás políticas usando uma ou mais dessas opções.

Um dos recursos das opções de expressões compactas é a possibilidade de expressar políticas através do aninhamento dos elementos básicos da política (chamados operadores nos termos da política, pois cada elemento implica em uma interpretação particular das asserções aninhadas) em qualquer ordem. As regras de aninhamento também definem uma interpretação do elemento <wsp:Policy> usado diretamente (sem o elemento filho <wsp:ExactlyOne> único necessário na forma normal) como equivalente ao elemento <wsp:All>, provavelmente o recurso de expressão compacto mais amplamente utilizado.

A Listagem 2 mostra uma expressão compacta da mesma política mostrada na Listagem 1, usando a representação <wsp:Policy> . Essa versão tem menos da metade do comprimento da primeira versão e a maioria das pessoas a considera mais fácil de ser entendida.

Listagem 2. Política simples na forma compacta
 <wsp:Policy>
                <sp:AsymmetricBinding
                xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                <wsp:Policy> <sp:InitiatorToken>
                <wsp:Policy> <sp:X509Token
                sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
                <wsp:Policy>
                <sp:RequireThumbprintReference/>
                </wsp:Policy> </sp:X509Token>
                </wsp:Policy> </sp:InitiatorToken>
                ...

A WS-Policy define um conjunto de transformações que pode ser aplicado para converter expressões de políticas usando as opções compactas na forma normal, então não há razão para usar a forma normal diretamente. É muito mais fácil para os computadores transformarem expressões compactas na forma normal do que humanos interpretarem a forma normal.

Inclusão de Política

Além de simplificar o aninhamento de elementos, a expressão compacta também fornece uma forma de referenciar e reutilizar expressões de políticas. Faça isso com o quarto elemento da WS-Policy, <wsp:PolicyReference>. Um elemento <wsp:PolicyReference> pode aparecer nos mesmos locais da asserção de política. A expressão de política referenciada é efetivamente substituída pela referência da política (tecnicamente com um elemento <wsp:All> substituindo o elemento <wsp:Policy> ). Essa abordagem de substituição é chamada de inclusão de política.

A Listagem 3 ilustra o uso de inclusão de política, mostrando a expressão de política da Listagem 2 refatorada para uma forma usando uma expressão de política separada e uma referência:

Listagem 3. Referência da política
                <!-- Client X.509 token policy assertion. -->
                <wsp:Policy wsu:Id="ClientX509"
                xmlns:wsu="http://.../oasis-200401-wss-wssecurity-utility-1.0.xsd">
                <sp:InitiatorToken> <wsp:Policy>
                <sp:X509Token
                sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
                <wsp:Policy>
                <sp:RequireThumbprintReference/>
                </wsp:Policy> </sp:X509Token>
                </wsp:Policy> </sp:InitiatorToken>
                </wsp:Policy> <wsp:Policy>
                <sp:AsymmetricBinding
                xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                <wsp:Policy> <wsp:PolicyReference
                URI="#ClientX509"/> ...

As referências às políticas podem ser usadas para expressões de políticas locais, conforme mostrado na Listagem 3, e para expressões de políticas externas. Para expressões de políticas externas, o atributo do URI de referência normalmente fornece a URL real da política externa.

Conforme será visto nos exemplos de teste de política fornecidos ainda neste artigo, a inclusão de política não é universalmente suportada no momento. Isso limita a função desse recurso interessante.

Alternativas da Política

Conforme visto anteriormente, a estrutura da WS-Policy suporta opções de alternativas como parte da política, através do elemento <wsp:ExactlyOne> . Com a expressão compacta, também é possível (pelo menos na teoria) usar atributos especiais para criar opções. De acordo com a recomendação da WS-Policy, é possível adicionar o atributo wsp:Optional="true" a qualquer asserção de política para tornar a asserção uma opção ao invés de um requisito, mesmo quando a asserção for um filho de um elemento <wsp:All> ou <wsp:Policy> .

As alternativas da política parecem ser um recurso útil, mas é difícil sugerir um exemplo concreto não trivial. Na prática, geralmente esses recursos são usados para tornar um componente particular do processo de segurança, como o UsernameToken, opcional. As alternativas mais complexas, como permitir ao cliente fornecer identificação na forma de um UsernameToken ou de um certificado X.509, parecem estar além dos recursos das implementações atuais do WS-SecurityPolicy.

Conexão de Política

No WSDL 1.1 (um pouco ultrapassado, mas ainda a forma de definição de serviço mais amplamente utilizada), as definições de serviço usam uma estrutura hierárquica. A primeira camada (na parte inferior) consiste nos elementos <wsdl:message> que definem a estrutura XML das mensagens enviadas e recebidas do serviço. A segunda camada consiste nos elementos <wsdl:portType> que definem os conjuntos de operações, com cada operação especificada pelas mensagens de entrada, saída ou de falha. A terceira camada consiste nos elementos <wsdl:binding> que associam um protocolo de mensagem particular (como o SOAP) e um método de acesso a um elemento <wsdl:portType>. A quarta camada são as definições do terminal em serviço na forma de elementos <wsdl:port> que especificam o endereço no qual um elemento <wsdl:binding> pode ser acessado.

A WS-Policy permite a conexão de políticas às definições de serviço WSDL em diversos pontos diferentes que não correspondem exatamente às camadas da definição. Considerando que as camadas representam uma estrutura lógica das definições de serviço, a WS-Policy está mais preocupada com mensagens e grupos de mensagens. Os quatro níveis de agrupamentos de mensagens usados pela WS-Policy são:

  • Mensagem: A política é aplicada a uma mensagem particular (sempre que a mensagem for usada se a política for anexada através do elemento <wsdl:message> ou quando usada por uma operação particular se for anexada através das definições de entrada/saída/falha da operação no elemento <wsdl:portType> ou no elemento <wsdl:binding> ).
  • Operação: A política é aplicada a todas as trocas de mensagens de uma operação particular (política anexada através do elemento <wsdl:operation> com <wsdl:binding> ou <wsdl:portType>).
  • Terminal: A política é aplicada a todas as trocas de mensagens de uma ligação de serviço particular (política anexada através de <wsdl:port> ou <wsdl:binding>) ou para todas as ligações de serviço baseadas em um tipo de porta particular (política anexada ao <wsdl:portType>).
  • Serviço: a política é aplicada a todos os terminais e operações associados a um serviço (política anexada no elemento <wsdl:service> ).

O principal mecanismo de conexão de políticas usado pelo WSDL é o mesmo usado para referenciar uma política em outra política — o elemento <wsp:PolicyReference> discutido na seção Inclusão de Política . Esse elemento da WS-Policy pode ser adicionado como um filho em qualquer elemento WSDL listado anteriormente para especificar a política a ser aplicada no nível de agrupamentos de mensagens. Também é possível incorporar uma política diretamente como um elemento <wsp:Policy> com qualquer conteúdo apropriado, mas normalmente é melhor usar referências para a estrutura do WSDL permanecer ordenada.

As políticas aplicadas em um nível dos agrupamentos de mensagens são herdadas pelas camadas inferiores, combinadas com um elemento <wsp:All> . Isso torna a política real (ou efetiva, nos termos da WS-Policy) aplicada a cada mensagem a conjunção de todas as políticas aplicadas nas camadas da mensagem, operação, terminal e serviço. Então a política não é determinada somente pela mensagem, mas também pelo contexto no qual a mensagem é usada

A Listagem 4 ilustra essa operação, mostrando o esqueleto da definição do WSDL com referências às políticas:

Listagem 4. Exemplo de conexão de política
 <wsdl:binding
                name="LibrarySoapBinding" type="wns:Library">
                <wsp:PolicyReference
                xmlns:wsp="http://www.w3.org/ns/ws-policy"
                URI="#UsernameToken"/> <wsdlsoap:binding
                style="document"
                transport="http://schemas.xmlsoap.org/soap/http"/>
                <wsdl:operation name="addBook">
                <wsp:PolicyReference
                xmlns:wsp="http://www.w3.org/ns/ws-policy"
                URI="#AsymmEncr"/> ... </wsdl:operation>
                </wsdl:binding>

Nesse caso, uma política que requer um UsernameToken foi anexada no nível <wsdl:binding> , e uma política adicional que requer criptografia de mensagem assimétrica foi anexada à operação addBook definida como parte dessa ligação. Assumindo que esse exemplo mostra o conjunto completo de referências às políticas do WSDL, o UsernameToken é sempre requerido, mas a autenticação da mensagem é somente usada para a operação addBook .

Como alternativa ao uso do <wsp:PolicyReference> para referenciar políticas diretamente dos elementos do WSDL, é possível usar o atributo wsp:PolicyURIs . É possível adicionar esse atributo a qualquer elemento do WSDL no qual uma política possa ser anexada. Funciona basicamente da mesma forma que usar elementos <wsp:PolicyReference> filhos.

Conexão de WS-SecurityPolicy

A WS-SecurityPolicy especifica os níveis de agrupamento de mensagens nos quais diferentes tipos de asserções de políticas podem ser anexados a uma descrição do serviço. Por exemplo: a asserção <sp:TransportBinding> usada para especificar a segurança do transporte só poderá ser anexada no nível do terminal, enquanto as asserções <sp:AsymmetricBinding> e <sp:SymmetricBinding> usadas para especificar criptografias ou autenticações de mensagens só poderão ser usadas no nível do terminal ou da operação.

Embora o <sp:AsymmetricBinding> ou o <sp:SymmetricBinding> não possa ser especificado no nível da mensagem, é possível especificar os componentes da mensagem a serem criptografados ou autenticados no nível da mensagem. Isso significa que, pelo menos na teoria, é possível especificar criptografia ou autenticação por mensagem.

Exemplos de Políticas

Agora que você aprendeu os princípios da WS-Policy e como ela funciona com o WSDL, é hora de testar alguns exemplos de políticas usando esses princípios. Assim como nos artigos anteriores, eu testei o código deste artigo com todas as três principais pilhas de serviços da Web de software livre Java: Axis2, Metro e CXF.

A Listagem 5 mostra um exemplo (effective1.wsdl no download do código de amostra) usando três níveis de conexão de política em uma definição de serviço WSDL. As três políticas usadas são:

  • UsernameToken: Requer um UsernameToken com uma senha hash.
  • SymmEncr: Requer uma criptografia simétrica usando uma chave genérica gerada pelo cliente.
  • EncrBody: Requer a criptografia do corpo da mensagem.
Listagem 5. Exemplo de política efetiva
 <wsdl:definitions
                targetNamespace="http://ws.sosnoski.com/library/wsdl"...>
                <wsp:Policy wsu:Id="UsernameToken"
                xmlns:wsp="http://www.w3.org/ns/ws-policy"...>
                <sp:SupportingTokens> <wsp:Policy>
                <sp:UsernameToken
                sp:IncludeToken=".../IncludeToken/AlwaysToRecipient">
                <wsp:Policy> <sp:HashPassword/>
                </wsp:Policy> </sp:UsernameToken>
                </wsp:Policy> </sp:SupportingTokens>
                </wsp:Policy> <wsp:Policy wsu:Id="SymmEncr"
                xmlns:wsp="http://www.w3.org/ns/ws-policy"...>
                <sp:SymmetricBinding> <wsp:Policy>
                <sp:ProtectionToken> <wsp:Policy>
                <sp:X509Token
                sp:IncludeToken=".../IncludeToken/Never"> ...
                </sp:X509Token> </wsp:Policy>
                </sp:ProtectionToken> ...
                </wsp:Policy> </sp:SymmetricBinding>
                ... </wsp:Policy> <wsp:Policy
                wsu:Id="EncrBody"
                xmlns:wsp="http://www.w3.org/ns/ws-policy"...>
                <sp:EncryptedParts> <sp:Body/>
                </sp:EncryptedParts> </wsp:Policy>
                ... <wsdl:binding name="LibrarySoapBinding"
                type="wns:Library"> <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#UsernameToken"/> ... <wsdl:operation
                name="getBook"> <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#SymmEncr"/> <wsdlsoap:operation
                soapAction="urn:getBook"/> <wsdl:input
                name="getBookRequest"> <wsdlsoap:body
                use="literal"/> </wsdl:input>
                <wsdl:output name="getBookResponse">
                    <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#EncrBody"/> <wsdlsoap:body
                use="literal"/> </wsdl:output>
                </wsdl:operation> <wsdl:operation
                name="getBooksByType">
                    <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#SymmEncr"/> <wsdlsoap:operation
                soapAction="urn:getBooksByType"/> <wsdl:input
                name="getBooksByTypeRequest"> <wsdlsoap:body
                use="literal"/> </wsdl:input>
                <wsdl:output name="getBooksByTypeResponse">
                    <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#EncrBody"/> <wsdlsoap:body
                use="literal"/> </wsdl:output>
                </wsdl:operation> <wsdl:operation
                name="getTypes"> ... </wsdl:operation>
                <wsdl:operation name="addBook">
                    <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#SymmEncr"/> <wsdlsoap:operation
                soapAction="urn:addBook"/> <wsdl:input
                name="addBookRequest">
                    <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#EncrBody"/> <wsdlsoap:body
                use="literal"/> </wsdl:input>
                <wsdl:output name="addBookResponse">
                <wsdlsoap:body use="literal"/>
                </wsdl:output> <wsdl:fault
                name="addDuplicateFault">
                    <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#EncrBody"/> <wsdlsoap:fault
                name="addDuplicateFault" use="literal"/>
                </wsdl:fault> </wsdl:operation>
                </wsdl:binding> ...
                </wsdl:definitions>

As referências às políticas (mostradas em negrito) no documento WSDL da Listagem 5 anexam a política UsernameToken ao <wsdl:binding>, então o UsernameToken será necessário em todas as operações. A política SymmEncr é anexada ao <wsdl:operation> individual para todas as operações de troca de informações de livro e a política EncrBody é anexada às mensagem que incluem informações de livro — para que as informações de livro sejam sempre enviadas na forma criptografada.

Essa é uma política complicada, pois requer que o cliente gere uma chave secreta e a envie para o servidor com a mensagem de solicitação, apesar de a chave secreta ser somente usada para criptografar a resposta. O Axis2 1.5.2 e o Metro 2.0.1 não são capazes de tratar esse caso de nenhuma forma. O Axis2 ignorou completamente os componentes da política que usam os namespaces de política WS-Policy 1.5. Quando eu alterei o uso para o namespace de envio o Axis2 foi além, gerando uma configuração razoável no código do cliente — mas ignorou a política no cliente e no servidor no tempo de execução, executando sem segurança. O Metro gerou uma mensagem de solicitação com um UsernameToken, mas sem informações da chave secreta.

O CXF 2.3.0 se saiu melhor, manipulando a política corretamente exceto em dois casos. Quando a operação addBook é bem-sucedida, a mensagem de resposta não usa criptografia. O servidor do CXF tratou isso corretamente, mas o cliente emitiu uma exceção ao processar a resposta O outro erro do CXF ocorreu com a operação addBook , mas nesse caso quando a solicitação falha. A resposta de retorno de falha do aplicativo deveria usar criptografia, mas o servidor do CXF enviou a resposta sem criptografia e o cliente a aceitou sem nenhuma queixa.

A política da Listagem 5 demonstra o uso seletivo da criptografia de mensagem, criptografando somente as mensagens que incluem informações de livros. No entanto, essa política usa criptografia simétrica. Seria ótimo poder fazer a mesma coisa usando criptografia assimétrica, na qual o cliente possui o seu próprio certificado (especialmente quando quiser assinar mensagens para verificação do remetente). A Listagem 6 mostra um exemplo projetado para esse propósito (effective2.wsdl no download). Esse exemplo usa somente duas políticas do WSDL:

  • AsymmBinding: Requer uma criptografia assimétrica usando certificados duplos.
  • SignBody: Requer a assinatura do corpo da mensagem.
Listagem 6. Exemplo de assinatura assimétrica
 <wsdl:definitions
                targetNamespace="http://ws.sosnoski.com/library/wsdl"...>
                <wsp:Policy wsu:Id="AsymmBinding"
                xmlns:wsp="http://www.w3.org/ns/ws-policy" ...>
                <sp:AsymmetricBinding> <wsp:Policy>
                <sp:InitiatorToken> <wsp:Policy>
                <sp:X509Token
                sp:IncludeToken=".../IncludeToken/AlwaysToRecipient"> ...
                </sp:X509Token> </wsp:Policy>
                </sp:InitiatorToken>
                <sp:RecipientToken> <wsp:Policy>
                <sp:X509Token
                sp:IncludeToken=".../IncludeToken/Never"> ...
                </sp:X509Token> </wsp:Policy>
                </sp:RecipientToken> ...
                </wsp:Policy>
                </sp:AsymmetricBinding>
                </wsp:Policy> <wsp:Policy wsu:Id="SignBody"
                xmlns:wsp="http://www.w3.org/ns/ws-policy" ...>
                <sp:SignedParts> <sp:Body/>
                </sp:SignedParts> </wsp:Policy> ...
                <wsdl:binding name="LibrarySoapBinding"
                type="wns:Library"> ... <wsdl:operation
                name="getBook"> <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#AsymmBinding"/>
                <wsdlsoap:operation soapAction="urn:getBook"/>
                <wsdl:input name="getBookRequest">
                <wsdlsoap:body use="literal"/>
                </wsdl:input> <wsdl:output
                name="getBookResponse">
                    <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#SignBody"/> <wsdlsoap:body
                use="literal"/> </wsdl:output>
                </wsdl:operation> <wsdl:operation
                name="getBooksByType">
                    <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#AsymmBinding"/>
                <wsdlsoap:operation
                soapAction="urn:getBooksByType"/> <wsdl:input
                name="getBooksByTypeRequest"> <wsdlsoap:body
                use="literal"/> </wsdl:input>
                <wsdl:output name="getBooksByTypeResponse">
                    <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#SignBody"/> <wsdlsoap:body
                use="literal"/> </wsdl:output>
                </wsdl:operation> <wsdl:operation
                name="getTypes"> ... </wsdl:operation>
                <wsdl:operation name="addBook">
                    <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#AsymmBinding"/>
                <wsdlsoap:operation soapAction="urn:addBook"/>
                <wsdl:input name="addBookRequest">
                    <wsp:PolicyReference
                    xmlns:wsp="http://www.w3.org/ns/ws-policy"
                    URI="#SignBody"/> <wsdlsoap:body
                use="literal"/> </wsdl:input>
                <wsdl:output name="addBookResponse">
                <wsdlsoap:body use="literal"/>
                </wsdl:output> <wsdl:fault
                name="addDuplicateFault"> <wsdlsoap:fault
                name="addDuplicateFault" use="literal"/>
                </wsdl:fault> </wsdl:operation>
                </wsdl:binding> ...
                </wsdl:definitions>

O exemplo da Listagem 6 usa criptografia assimétrica para assinar todas as mensagens que fornecem informações de livro. Isso significa que as mensagens de resposta getBook e getBooksByType devem ser assinadas pelo servidor, enquanto a mensagem de solicitação addBook deve ser assinada pelo cliente. Como a criptografia assimétrica está sendo usada, na qual cada lado possui seu próprio certificado e chave privada, esse exemplo deveria ser mais simples de ser tratado do que o exemplo de criptografia simétrica da Listagem 5 .

O Axis2 falhou da mesma forma que ocorreu exemplo anterior, ignorando completamente os componentes da política que usam os namespaces de política WS-Policy 1.5 e gerando a política do cliente, mas ignorando-a em ambos os lados quanto eu mudei para o namespace de envio. (Para obter um exemplo mais simples das políticas efetivas que funcionam com o Axis2, consulte o artigo "Serviços da Web Java: Uso Granular do WS-Security.")

O Metro não foi capaz de trabalhar com a configuração de política fornecida, emitindo um NullPointerException no cliente com a primeira solicitação. Após alguma investigação, descobri que o problema é resolvido ao anexar uma política no nível do terminal, ao invés de anexá-la somente nos níveis de operação e de mensagem. O exemplo do Metro inclui um effective3.wsdl com a política #AsymmBinding referenciada somente para o <wsdl:binding>, e esse exemplo foi executado sem problemas (apesar de, como ocorreu com o CXF no caso simétrico, o Metro não aplicar a segurança na resposta de falha do aplicativo).

O CXF também falhou com a configuração de política da Listagem 6 , mas sem uma solução alternativa fácil no código atual. O código do cliente CXF gerou de forma incorreta uma assinatura ao enviar a mensagem de solicitação getBook e o código do servidor falhou no processamento da mensagem de solicitação. Então parece que o código CXF atual insiste em gerar uma assinatura quando um AsymmetricBinding é usado, mesmo quando nada está sendo assinado.

Conclusão da Política

A WS-Policy define uma estrutura flexível e poderosa para expressar qualquer forma de restrição. Infelizmente, as implementações dos processamentos da WS-Policy e da WS-SecurityPolicy usados pelas pilhas de serviços da Web não implementam muito essa flexibilidade. Devido a essa falta de suporte na implementação, muitos outros recursos úteis da WS-Policy não podem ser usados para serviços da Web projetados para interoperar com uma ampla gama de pilhas de serviços da Web.

O processamento básico de políticas efetivas, nas quais as políticas são anexadas em diferentes pontos nas definições de serviço do WSDL, é o recurso principal do design da política e do WSDL e deveria ser usado quando apropriado para os seus serviços. Mas um dos possíveis recursos úteis desse tipo de configuração — a possibilidade de assinar e criptografar mensagens seletivamente de forma individual — não funciona com segurança. Devido a essa limitação, provavelmente é melhor permanecer com as conexões de políticas nos níveis <wsdl:binding> e <wsdl:operation> por enquanto para uma melhor interoperabilidade.

As políticas externas podem ser especialmente úteis em ambientes do tipo SOA, nos quais um conjunto de políticas comuns pode ser configurado para uso por toda a organização e cada serviço pode referenciar as políticas apropriadas de acordo com as necessidades. Apesar desse recurso não ser suportado no momento por todas as pilhas de serviços da Web Java de software livre (somente o Apache CXF suporta o recurso corretamente), as grandes organizações podem optar por usar o recurso de qualquer forma e restringir as implementações de serviços da Web usando uma das pilhas (de software livre ou comercial) que ofereça suporte. Também é possível obter o mesmo efeito de outras formas, como através do uso do conteúdo do WSDL.

No próximo artigo da série, eu resumirei os problemas de desempenho e de interoperabilidade com as três principais pilhas de serviços da Web Java e apresentarei uma visão geral da comparação dessas pilhas para uso na implementação de serviços da Web seguros. Se usar serviços da Web seguros na sua organização, não perca o próximo artigo.


Recursos para download


Temas relacionados

  • O W3C Web Services Policy Working Group: Esse grupo define a especificação da WS-Policy.
  • OASIS Web Services Secure Exchange (WS-SX) TC: Essa organização é responsável pelas especificações da WS-SecurityPolicy, da WS-SecureConversation e da WS-Trust.
  • Esquemas do WSDL 1.1: As especificações do WSDL 1.1 incluem uma definição de esquema que não corresponde ao texto. Esse esquema foi substituído posteriormente por esse esquema, apesar do texto do WSDL 1.1 nunca ter sido atualizado para refletir a alteração. A organização de interoperabilidade WS-I definiu uma terceira versão, que provavelmente é a melhor de todas.
  • "Understand WS-Policy processing" (Paul Nolan, developerWorks, dezembro de 2004): Esse artigo aborda os detalhes da normalização e da comparação da WS-Policy.
  • Apache Axis2/Java: Visite a página inicial do projeto do mecanismo de serviços da Web Axis2.
  • Metro: Visite o Web site do Metro para obter documentações e efetuar downloads.
  • Apache CXF: Visite o site da pilha de serviços da Web CXF.

Comentários

Acesse ou registre-se para adicionar e acompanhar os comentários.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Tecnologia Java, WebSphere, Software livre
ArticleID=594724
ArticleTitle=Serviços da Web Java: Entendendo a WS-Policy
publish-date=12062010