Skip to content

Instantly share code, notes, and snippets.

@alexandreaquiles
Created December 4, 2015 19:33
Show Gist options
  • Save alexandreaquiles/513f22fe80f345a4dc92 to your computer and use it in GitHub Desktop.
Save alexandreaquiles/513f22fe80f345a4dc92 to your computer and use it in GitHub Desktop.
Autorizador usando SOAPHandler.

No exercício 3.27, recebemos o token do <Header> do Envelope SOAP colocando o parâmetro com header=true e, dentro do método, comparamos o token recebido com o token esperado.

@Stateless
@WebService(targetNamespace="http://caelum.com.br/estoquews/v1")
public class EstoqueWS {
  //...
  @WebMethod(operationName="ItensPeloCodigo")
	@WebResult(name="ItemEstoque")
	public List<ItemEstoque> getQuantidade(
		@WebParam(name="codigo") List<String> codigos,
		@WebParam(name="tokenUsuario", header=true) String token) {
		  if(token == null || !token.equals("TOKEN123")) {
		    throw new AutorizacaoException("Não autorizado.");
		  }
		  //...
	}
}

Mas imagina só se TODO método tivesse que receber esse parâmetro e ter esse if? Muito tosco!

Dá pra melhorar esse código usando um SOAPHandler do JAX-WS.

Precisamos criar uma classe que implementa a interface SOAPHandler. Se o método handleMessage retornar false ou alguma exceção for lançada, o request ao WebService é barrado. Veja a classe Autorizador acima:

  • obtemos o SOAPEnvelope através do contexto
  • o envelope através do SOAPHeader
  • o token através do header.

Perceba na classe EstoqueWS acima, que não temos mais o parâmetro nem o if e utilizamos a anotação @HandlerChain apontando para o arquivo handlers.xml.

@Stateless
@HandlerChain(file="handlers.xml")
@WebService(targetNamespace="http://caelum.com.br/estoquews/v1")
public class EstoqueWS {
  //...
  @WebMethod(operationName="ItensPeloCodigo")
	@WebResult(name="ItemEstoque")
	public List<ItemEstoque> getQuantidade(
		@WebParam(name="codigo") List<String> codigos) {
		//...
	}
}

O arquivo handlers.xml deve ficar no mesmo pacote do EstoqueWS e aponta para a classe Autorizador.

package br.com.caelum.estoque.ws.handler;
import java.util.Iterator;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.Node;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class Autorizador implements SOAPHandler<SOAPMessageContext>{
@Override
public boolean handleMessage(SOAPMessageContext context) {
if((Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)){
return true;
}
try {
SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
SOAPHeader soapHeader = envelope.getHeader();
Iterator elements = soapHeader.getChildElements(new QName("http://caelum.com.br/estoquews/v1", "tokenUsuario"));
if(elements.hasNext()){
Node token = (Node) elements.next();
if("TOKEN123".equals(token.getValue())) {
return true;
}
}
throw new RuntimeException("Não autorizado.");
} catch (SOAPException e) {
throw new RuntimeException(e);
}
}
@Override
public boolean handleFault(SOAPMessageContext context) {
return true;
}
@Override
public void close(MessageContext context) {
}
@Override
public Set<QName> getHeaders() {
return null;
}
}
package br.com.caelum.estoque.ws;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.Stateless;
import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlElement;
@Stateless
@WebService(targetNamespace="http://caelum.com.br/estoquews/v1")
@HandlerChain(file="handlers.xml")
public class EstoqueWS {
private Map<String, ItemEstoque> repositorio = new HashMap<>();
public EstoqueWS() {
repositorio.put("SOA", new ItemEstoque("SOA", 5));
repositorio.put("TDD", new ItemEstoque("TDD", 1));
repositorio.put("RES", new ItemEstoque("RES", 2));
repositorio.put("LOG", new ItemEstoque("LOG", 4));
repositorio.put("WEB", new ItemEstoque("WEB", 1));
repositorio.put("ARQ", new ItemEstoque("ARQ", 2));
}
@WebMethod(operationName="ItensPeloCodigo")
@WebResult(name="ItemEstoque")
public List<ItemEstoque> getQuantidade(
@WebParam(name="codigo") List<String> codigos) {
ArrayList<ItemEstoque> itens = new ArrayList<>();
if (codigos == null || codigos.isEmpty()) {
return itens;
}
for (String codigo : codigos) {
if(repositorio.containsKey(codigo)){
itens.add(repositorio.get(codigo));
}
}
return itens;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/javaee_web_services_metadata_handler_2_0.xsd">
<javaee:handler-chain>
<javaee:handler>
<javaee:handler-name>autorizador</javaee:handler-name>
<javaee:handler-class>br.com.caelum.estoque.ws.handler.Autorizador</javaee:handler-class>
</javaee:handler>
</javaee:handler-chain>
</javaee:handler-chains>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment