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