Avançar para a área de conteúdo

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

A primeira vez que acessar o developerWorks, um perfil será criado para você. Informações do seu perfil (tais como: nome, país / região, e empresa) estarão disponíveis ao público, que poderá acompanhar qualquer conteúdo que você publicar. Seu perfil no developerWorks pode ser atualizado a qualquer momento.

Todas as informações enviadas são seguras.

  • Fechar [x]

Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

Todas as informações enviadas são seguras.

  • Fechar [x]

Entendendo Especificações de Serviços da Web, Parte 4: WS-Security

Nicholas Chase, Freelance writer, Backstop Media
Nicholas Chase esteve envolvido no desenvolvimento de Web sites para empresas como a Lucent Technologies, a Sun Microsystems, a Oracle e a Tampa Bay Buccaneers. Nick foi professor de física para turmas de ensino médio, gerente de instalação de resíduos radioativos de nível inferior, editor de revista de ficção científica on-line, engenheiro de multimídia, instrutor de Oracle e Chief Technology Officer de uma empresa de comunicações interativas. Ele é autor de diversos livros, incluindo XML Primer Plus (Sam's).

Resumo:  Há poucos (se algum) sistemas de nível corporativo que não requerem uma ou outra forma se segurança. Em serviços da Web, esse processo é mais complicado do que em outras áreas devido à sua natureza stateless distribuída. Este tutorial, Parte 4 da série Entendendo as Especificações de Serviços da Web, explica os conceitos por trás de WS-Security e padrões relacionados, como Assinatura XML, que se combinam para tornar a segurança no mundo de serviços da Web não apenas possível, mas prático.

Visualizar mais conteúdo nesta série

Data:  16/Set/2011
Nível:  Intermediário

Atividade:  4357 visualizações

Visão Geral

Antes de falarmos sobre como proteger um serviço, é útil saber exatamente quais são as partes que formam esse serviço para saber o que precisar ser feito.

A história até agora

Esta série de tutoriais as explorações da equipe do jornal The Daily Moon, que descobriu uma nova maneira de trabalhar na forma de serviços da Web. Tudo começou no departamento de classificados, que decidiu permitir que outros acessassem seus sistemas por meio do uso de mensagens SOAP -- mensagens XML que podem ser enviadas por HTTP.


Por exemplo, uma solicitação para o número de anúncios classificados na subcategoria "à venda" pode ter a aparência da Listagem 1.



Listagem 1. Uma mensagem SOAP de amostra
                    
<?xml version='1.0' ?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/SOAP-envelope"> 
 <env:Header>
 </env:Header>
 <env:Body>
  <cms:getNumberOfArticles xmlns:cms="http://www.daily-moon.com/cms">
    <cms:category>classifieds</cms:category>
    <cms:subcategory>forsale</cms:subcategory>
  </cms:getNumberOfArticles>
 </env:Body>
</env:Envelope>

A mensagem geral é chamada de Envelope, o conteúdo do qual consiste em Cabeçalho e Corpo. O Cabeçalho contém informações sobre a própria mensagem, como informações de roteamento, informações que devem ser processadas por "intermediários SOAP" ou serviços entre o remetente e o destinatário final, que pode processar a mensagem. (Neste caso, consulte qualquer um desses cabeçalhos, mas é lá que nossas informações de segurança estarão.) O Corpo da mensagem inclui a "carga útil", que inclui os dados em si a serem passados ao serviço da Web.

Neste caso, a carga útil é o elemento getNumberOfArticles e seu conteúdo.

Gene e Frances, do departamento de TI do jornal, criaram um sistema para atender solicitações de serviços da Web, assim como a infraestrutura para descobrir e criar clientes automaticamente para os serviços. Agora o editor do jornal, Rudy, está insistindo para que encontrem uma maneira de evitar acesso não autorizado a esses sistemas.


A necessidade de segurança

A especificação SOAP básica não prevê a proteção de mensagens, deixando essa tarefa para especificações estendidas. O problema está na natureza de um aplicativo de serviços da Web. Na maioria dos casos, estamos lidando com SOAP sobre HTTP, o que significa que cada mensagem precisa viajar por um ou mais nós, qualquer um dos quais podendo ler e/ou alterar uma mensagem. E isso é supondo que a solicitação SOAP em si foi direta. Em alguns casos, as mensagens SOAP são projetadas especificamente para viajar por meio de mais de um nó antes de chegar a seu destino final.

O resultado final é que precisamos de uma maneira para evitar que alguém além do destinatário desejado leia as informações sigilosas, para evitar escuta. Também precisamos de uma maneira para evitar que alguém além do remetente desejado envie as mensagens para evitar acesso não autorizado.

A especificação SOAP fornece um meio para incluir informações de segurança -- incluímos informações em um elemento Cabeçalho do Envelope -- mas não especifica quais deveriam ser essas informações. Para cuidar disso, precisamos de WS-Security.


As partes de WS-Security

Há três problemas principais envolvidos a proteção de trocas de mensagens SOAP e WS-Security fornece respostas a todos eles, mas não diretamente. É, na verdade, uma especificação que fala não sobre como proteger a mensagem, mas como informar o remetente como você protegeu a mensagem. Para realizar a proteção em si, WS-Security faz referência a especificações adicionais. Vamos ver como isso funciona.

O primeiro problema é identificar e autenticar o cliente. Como há diversas maneiras diferentes para criar tokens de segurança, WS-Security não especifica nenhum meio específico, mas define como diferentes tokens de segurança devem ser transferidos dentro de mensagens SOAP. Em outras palavras, permite que o destinatário saiba como extrair tokens de segurança da mensagem para processamento.

O segundo problema é assegurar integridade da mensagem. WS-Security usa assinaturas digitais para isso, empregando a especificação Assinatura XML em vez de inventar algo novo. Assinatura XML é uma recomendação do W3C que fornece um mecanismo para assinar documentos XML digitalmente.

O terceiro problema é manter a mensagem segura contra escuta enquanto está em trânsito. Mais uma vez, WS-Security emprega outro padrão do W3C, desta vez, a Criptografia XML, que fornece um mecanismo para criptografar documentos XML.

Neste tutorial, vamos ver como o uso desses padrões afeta as mensagens SOAP em si usadas, à medida que Gene e Frances trabalham para proteger o serviço de Classificados existente.


O serviço atual

Antes de pensar em fazer mudanças, é útil ver de onde Gene e Frances estão começando. O serviço de Classificados está implementado usando o Axis2, o que significa que está contido em um arquivo *.aar. O arquivo CMSService.aar consiste em três arquivos, conforme mostrado na Listagem 2.


Listagem 2. O conteúdo do serviço original
                    
CMSService.class
meta-inf/Manifest.MF

meta-inf/services.xml

A classe em si é direta, recebendo uma mensagem SOAP que lista uma categoria e retornando uma mensagem SOAP que inclui o número de anúncios para aquela categoria. Ela executa essa função conforme definido pelo arquivo services.xml (consulte Listagem 3).


Listagem 3. O arquivo services.xml original
                    
<service name="CMSService">

    <description>
        This is a sample web service for the newspaper's 
        Content Managment System.
    </description>

    <parameter name="ServiceClass" 
               locked="false">CMSService</parameter>

    <operation name="getNumberOfArticles">
        <messageReceiver class=
"org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
    </operation>

</service>

A proteção do serviço envolve tocar somente o arquivo services.xml; Gene e Frances não precisarão tocar a classe Java em si de forma alguma.


O cliente atual

O cliente em si é bastante direto e simplesmente faz e exibe a solicitação, conforme mostrado na Listagem 4:


Listagem 4. A classe do cliente original
                    
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.soap.SOAPFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.ConfigurationContextFactory;

public class ClassifiedClient {
    private static EndpointReference targetEPR = 
           new EndpointReference(
               "http://localhost:8888/axis2/services/CMSService");

    public static OMElement getNumOfArticlesOMElement() {
        SOAPFactory fac = OMAbstractFactory.getSOAP12Factory();
        OMNamespace omNs = fac.createOMNamespace(
                "http://daily-moon.com/cms", "cms");
        OMElement method = fac.createOMElement("getNumberOfArticles",
                                                omNs);
        OMElement value = fac.createOMElement("category", omNs);
        value.addChild(fac.createOMText(value, "classifieds"));
        method.addChild(value);

        return method;
    }

    public static void main(String[] args) {
        try {
            OMElement payload = 
               ClassifiedClient.getNumOfArticlesOMElement();
  
            Options options = new Options();
            options.setTo(targetEPR);
            options.setTransportInProtocol(Constants.TRANSPORT_HTTP);

            ServiceClient sender = new ServiceClient();

            sender.setOptions(options);
            OMElement result = sender.sendReceive(payload);

            String response = result.getText();
            System.out.println("There are "+response+
                               " classifieds at the moment.");
        } catch (Exception e) { 
        	System.out.println(e.toString());
        }
    }
}

Observe que Gene alterou a porta do terminal para 8888, em vez de 8080, a porta na qual o Geronimo está atendendo. Ele fez isso para inserir uma etapa adicional, de forma que ele possa ver as mensagens indo e vindo.


Vendo as mensagens

Para ver as mensagens SOAP em si, faça download de TCPMon a partir de http://ws.apache.org/commons/tcpmon/download.cgi. (Sim, o Axis2 vem com SOAPMonitor, mas Gene descobriu, da forma mais difícil, que além da dificuldade para configurar as coisas, mostra o SOAP, mas não necessariamente as mensagens brutas, o que vamos querer ver especificamente.)

Após fazer download, descompacte o aplicativo e execute o arquivo tcpmon-1.0-bin\build\tcpmon.bat . Clique na guia Admin e crie um novo listener, conforme visto na Figura 1.


Figura 1. A guia Admin do TCPMon

Escolha 8888 como a porta na qual atender e especifique 8080 como o ponto de destino para que TCPMon fique entre o cliente e o servidor. Clique em Add e, em seguida, clique na guia Port 8888. Clique na caixa de opção XML Format. Agora, quando Frances executar o cliente, Gene poderá ver a solicitação e a resposta, como na Figura 2.


Figura 2. A solicitação e resposta originais

Antes de seguir em frente, vamos dar uma olhada rápida nas mensagens em si para que possamos ver o que muda.


As mensagens

As mensagens em si são bem diretas. A solicitação, conforme visto a Listagem 5, simplesmente pede o número de anúncios classificados no sistema:


Listagem 5. A solicitação original
                    
<?xml version='1.0' encoding='UTF-8'?>
   <soapenv:Envelope
 xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
      <soapenv:Header />
      <soapenv:Body>
         <cms:getNumberOfArticles 
                    xmlns:cms="http://daily-moon.com/cms">
            <cms:category>classifieds</cms:category>
         </cms:getNumberOfArticles>
      </soapenv:Body>
   </soapenv:Envelope>
   

A resposta é igualmente direta, como é possível ver na Listagem 6:



Listagem 6: A resposta original
                    

<?xml version='1.0' encoding='UTF-8'?>
   <soapenv:Envelope xmlns:soapenv=
           "http://schemas.xmlsoap.org/soap/envelope/">
      <soapenv:Header />
      <soapenv:Body>
         <resp:numberOfArcticles 
               xmlns:resp="http://daily-moon.com/cms/"  
               xmlns:tns="http://ws.apache.org/axis2"
                            >42</resp:numberOfArcticles>
      </soapenv:Body>
   </soapenv:Envelope>

Em ambas as mensagens, Frances colocará informações adicionais no elemento Header para que o servidor (ou o cliente) processe.

No momento, qualquer pessoa pode enviar uma solicitação e obter uma resposta e isso é o que deixa Rudy nervoso. Ele quer que o serviço seja configurado de forma que somente usuários autorizados possam obter informações e, assim, que a concorrência não possa interceptar as informações. Rudy acredita que esse seja um bom sistema de prova de conceito. Ele, na verdade, está mais preocupado com sistemas mais complexos, como aqueles que incluem conteúdo ou acesso ao sistema de contabilidade. Mas os conceitos são os mesmos.

Para fornecer essa segurança, Gene e Frances precisam usar criptografia e sua tecnologia relacionada, assinaturas.

2 de 11 | Anterior | Próximo

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Tecnologia Java
ArticleID=757426
TutorialTitle=Entendendo Especificações de Serviços da Web, Parte 4: WS-Security
publish-date=09162011
author1-email=ibmquestions@nicholaschase.com
author1-email-cc=