Páginas

jueves, 12 de enero de 2012

Autenticación JAX-WS UsernameToken desde cliente

En este POST se pretende mostrar como configurar un cliente JAX-WS que consuma un servicio que requiera autenticación a través de UsernameToken.

A continuación se indican las librerías necesarias para la implementación del ejemplo así como sus coordenadas para la herramienta Maven.

  • jaxb-impl
    • groupId: com.sun.xml.bind
    • artifactId: jaxb-impl
  • xws-security
    • groupId: com.sun.xml.wss
    • artifactId: xws-security
  • xmlsec
    • groupId: com.sun.org.xml.security
    • artifactId: xmlsec
  • jaxp-api
    • groupId: javax.xml
    • artifactId: jaxp-api
  • xercesImpl
    • groupId: activesoap
    • artifactId: xercesImpl
  • jaxb-xalan
    • groupId: activesoap
    • artifactId: jaxb-xalan
Acceso al servicio

 URL url = new URL("http://rutaAplicacion/nombreServicio");
 QName qname = new QName("e3swsdl-master", "nombreServicio");
NombreServicioService locator = new NombreServicioService(url, qname);
NombreServicio port = locator.getPort(NombreServicio.class);
//Manejador
final List<Handler> chain = new ArrayList<Handler>();
 chain.add(new SecurityHandler());
 ((BindingProvider) port).getBinding().setHandlerChain(chain);
 //Llamada operación del servicio
 port.metodoServicio(...);


Manejador

import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import com.sun.xml.wss.ProcessingContext;
import com.sun.xml.wss.XWSSProcessor;
import com.sun.xml.wss.XWSSProcessorFactory;
import com.sun.xml.wss.XWSSecurityException;

public class SecurityHandler implements SOAPHandler<SOAPMessageContext> {

 XWSSProcessor cprocessor = null;

 public SecurityHandler() {
 //Leemos el archivo de configuración del servidor
 final InputStream input = this.getClass().getResourceAsStream("/user-pass-authenticate-client.xml");

 try {
 // inicializamos el XWSSProcessor
 final XWSSProcessorFactory factory = XWSSProcessorFactory.newInstance();
 cprocessor = factory.createProcessorForSecurityConfiguration(input, new SecurityEnvironmentHandler());
 input.close();

 } catch (final XWSSecurityException e) {
 //TODO tratar la excepción
 throw new RuntimeException(e);
 } catch (final IOException e) {
 //TODO tratar la excepción
 }

 }

 public Set<QName> getHeaders() {
 final QName securityHeader = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "wsse");
 final HashSet<QName> headers = new HashSet<QName>();
 headers.add(securityHeader);
 return headers;
 }

 public boolean handleFault(final SOAPMessageContext messageContext) {
 return true;
 }

 public boolean handleMessage(final SOAPMessageContext messageContext) {
 return secureClient(messageContext);

 }

 public void close(final MessageContext messageContext) {
 }

 private boolean secureClient(final SOAPMessageContext messageContext) {
 final Boolean outMessageIndicator = (Boolean) messageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
 final SOAPMessage message = messageContext.getMessage();
 boolean ok = false;
 if (outMessageIndicator.booleanValue()) {
 ProcessingContext context;
 try {
 context = cprocessor.createProcessingContext(message);
 context.setSOAPMessage(message);
 final SOAPMessage secureMsg = cprocessor.secureOutboundMessage(context);
 secureMsg.writeTo(System.out);
 messageContext.setMessage(secureMsg);
 ok = true;
 } catch (final Exception e) {
 e.printStackTrace();
 throw new RuntimeException(e);
 }
 } else {
 ok = false;
 }
 return ok;
 }
}




Seguridad

import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import com.sun.xml.wss.impl.callback.PasswordCallback;
import com.sun.xml.wss.impl.callback.UsernameCallback;

/**
 * Handle the WSS user/pass security.
 */
public class SecurityEnvironmentHandler implements CallbackHandler {

 public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException {
 for (final Callback callback : callbacks) {
 if (callback instanceof UsernameCallback) {

 final UsernameCallback cb = (UsernameCallback) callback;
 final String userName = "USUARIO";
 if (userName == null) {
 throw new IOException("La configuaricion del parametro '" + "USARIO" + "' es requerida");
 }
 cb.setUsername(userName);

 } else if (callback instanceof PasswordCallback) {
 final String pass = "CLAVE";
 if (pass == null) {
 throw new IOException("La configuaricion del parametro '" + "CLAVE" + "' es requerida");
 }

 final PasswordCallback cb = (PasswordCallback) callback;
 cb.setPassword(pass);
 }
 }
 }
}


Configuración del manejador
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" dumpMessages="true" >
 <xwss:UsernameToken digestPassword="false"/>
</xwss:SecurityConfiguration>

Este mágnifico ejemplo debemos agradecerlo a los compañeros del blog Xnoccio donde podemos consultar el ejemplo original haciendo clic aqui

3 comentarios:

  1. Este archivo: user-pass-authenticate-client.xml donde se ubica o que contiene? gracias.

    ResponderEliminar
  2. Buenas Tardes

    estoy tratando de implementar un web service con autenticacion username token soy prinipiante. donde devo colocar Acceso al servicio

    Gracias.

    ResponderEliminar
  3. Este archivo: user-pass-authenticate-client.xml donde se ubica o que contiene? gracias.

    ResponderEliminar