martedì 14 agosto 2012

Web Service con WS-Security seconda parte (CLIENT)

Per generare un client di un Web Service messo in sicurezza come visto nel precedente post occorre per prima cosa tramite l'utility wsimport (vedi qui ) generare le classi del client e dopo aggiungere l'handler che si occuperà in questo caso di scrivere username e password nell'header soap.

Ho scritto 2 classi una è l'implementazione dell'HandlerResolver usati in JAX-WS 2.0 proprio per "prendere il controllo" della eventuale catena di Handler presenti (in questo caso sarà soltanto uno).

Poi invece bisogna scrivere l'handler specifico che implementerà al solito l'interfaccia SOAPHandler.


MyHandler

import java.util.ArrayList;
import java.util.List;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;
import javax.xml.ws.handler.soap.SOAPHandler;
public class MyHandler implements HandlerResolver {

    @Override
    public List<Handler> getHandlerChain(PortInfo portInfo) {
        List<Handler> handlerList = new ArrayList<Handler>();
        SOAPHandler handler =  new WSSecurityHandler();
        handlerList.add(handler);
        return handlerList;
    }

}

WsSecurityHandler

package it.handler;

import java.io.IOException;
import java.util.Set;
import java.util.TreeSet;

import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
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;
/**
 * Handler che gestisce il passaggio <br>
 * di username e password nell'header soap
 * @author
 *
 */
public class WSSecurityHandler implements SOAPHandler {
    private boolean scriviOutputSuConsole=true;
    /**
     * INSERIRE LO USERNAME
     */
    public static final String USER_NAME="pippo";
    /**
     * INSERIRE LA PWD 
     */
    public static final String PWD="pluto";
    @Override
    public void close(MessageContext arg0) {
        if(scriviOutputSuConsole) System.out.println("CLOSE");
    }

    @Override
    public boolean handleFault(MessageContext context1) {
        SOAPMessageContext context = (SOAPMessageContext)context1;
        try {
            if(scriviOutputSuConsole)context.getMessage().writeTo(System.out);
        } catch (SOAPException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return false;
    }

    @Override
 
    public boolean handleMessage(MessageContext context1) {
        SOAPMessageContext context = (SOAPMessageContext)context1;
        Boolean outbound = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outbound.booleanValue())
        {
            try {
                SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
                SOAPFactory factory = SOAPFactory.newInstance();
                String prefix = "wsse";
                String uri = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
                SOAPElement securityElement = factory.createElement("Security", prefix, uri);
                QName nameMust = new QName(envelope.getPrefix()+":mustUnderstand");
                securityElement.addAttribute(nameMust, "1");
                securityElement.addNamespaceDeclaration("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
                SOAPElement tokenElement = factory.createElement("UsernameToken", prefix, uri);
                QName nameWSU = new QName("wsu:Id");
                tokenElement.addAttribute(nameWSU, "token-1-1236072936329-25515818");
                SOAPElement username = factory.createElement("Username", prefix, uri);
                username.addTextNode(USER_NAME);
                SOAPElement pwd = factory.createElement("Password", prefix, uri);
                pwd.addTextNode(PWD);
                tokenElement.addChildElement(username);
                tokenElement.addChildElement(pwd);
                securityElement.addChildElement(tokenElement);
                SOAPHeader header = envelope.addHeader();
                header.addChildElement(securityElement);
                if(scriviOutputSuConsole) context.getMessage().writeTo(System.out);
               
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        else
        {
        }
        return true;
    }

    @Override
    public Set getHeaders() {
        return new TreeSet();
    }
}



A questo punto dal nostro client Java dobbiamo scrivere il seguente codice (supponiamo di aver messo in sicurezza il Web Service visto in questo post )

FattorialeDaoImplService f=new FattorialeDaoImplService();
CalcoloWs port=f.getCalcoloWsPort();
HandlerResolver resolver = new MyHandler();
f.setHandlerResolver(resolver);    
         
long fatt=port.getFattoriale(5);                 
System.out.println(fatt);



1 commento:

  1. Grazie, il tuo articolo mi ha risolto un po' di problemi.
    Umberto

    RispondiElimina