UsernameToken en Jax-ws (2/2) – Cliente

25 Jun 2010

Compartelo:Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0

El objetivo de este artículo es mostrar como implementar crear un cliente Jax-ws que consuma servicios securizados con   UsernameToken según la especificación Web Services Security UsernameToken Profile 1.0.

El artículo consiera que el lector ya tiene experiencia en Jax-ws y se centra sólo en la configuración del mecanismo de seguridad  consumir servicios que requieran la identificación del solicitante con usuario y password haciendo uso de Jax-ws.

Dependencias requeridas

Aunque las dependencias necesarias están incluidas en algunos servidores de aplicaciones, si lo deseamos podemos o bien bajar la implementación de referencia directamente desde su web:

https://jax-ws-commons.dev.java.net y https://jax-ws.dev.java.net

O definir la dependencia en caso de que el proyecto sea Maven.

[code]
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.1.12</version>
</dependency>

<dependency>
<groupId>com.sun.xml.wss</groupId>
<artifactId>xws-security</artifactId>
<version>3.0</version>
</dependency>

<dependency>
<groupId>com.sun.org.apache.xml.security</groupId>
<artifactId>xmlsec</artifactId>
<version>2.0</version>
</dependency>

<dependency>
<groupId>javax.xml</groupId>
<artifactId>jaxp-api</artifactId>
<version>1.4.2</version>
</dependency>

<dependency>
<groupId>activesoap</groupId>
<artifactId>xercesImpl</artifactId>
<version>1.5</version>
</dependency>

<dependency>
<groupId>activesoap</groupId>
<artifactId>jaxb-xalan</artifactId>
<version>1.5</version>
</dependency>
[/code]

Configuaramos el acceso al Servicio

[code lang=”java”]

URL url = new URL("http://rutaAplicacionDeEjemplo/IE3SEnvironmentalMasterData");
QName qname = new QName("e3swsdl-master", "IE3SEnvironmentalMasterData");
IE3SEnvironmentalMasterDataService locator = new IE3SEnvironmentalMasterDataService(url, qname);
IE3SEnvironmentalMasterData clienteProxy = locator.getPort(IE3SEnvironmentalMasterData.class);

//Añadimos el manejador
final List<Handler> chain = new ArrayList<Handler>();
chain.add(new SecurityHandler());
((BindingProvider) clienteProxy).getBinding().setHandlerChain(chain);

//Accedemos al servicio
clienteProxy.addTemporaryProducerCenterData(null, null, null, null, holder);

[/code]

Creamos el manejador (SecurityHandler.java)

[code lang=”java”]
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;
}
}
[/code]

Creamos la clase que maneja la seguridad (SecurityEnvironmentHandler.java)

[code lang=”java”]
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);
}
}
}
}
[/code]

Configuramos el manejador (user-pass-authenticate-client.xml)

[code]
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" dumpMessages="true" >
<xwss:UsernameToken digestPassword="false"/>
</xwss:SecurityConfiguration>
[/code]

Nuestra petición de acceso debe contener el usuario y contraseña de acceso en la cabecera de la petición http siendo similar a la siguiente

[code]
<pre><code><?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" S:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="XWSSGID-1255949753848350309586">
<strong><wsse:Username>usuario</wsse:Username></strong>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">****</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">9w+YwOatF9l1/otioQ75d5Yr</wsse:Nonce>
<wsu:Created>2009-10-19T10:55:54.418Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</S:Header>
<S:Body>
</S:Body>
</S:Envelope>
</code></pre>
[/code]

Post relacionados

Compartelo:Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0

6 Respuestas to “UsernameToken en Jax-ws (2/2) – Cliente”

  1. Daniel 15 de Febrero de 2011 at 0:22 #

    Very helpful.. thanks a lot.

  2. Jesús López 24 de Marzo de 2011 at 11:06 #

    Desconosco si desde netbeans lo puedes probar de forma gráfica la verdad, lo que si es verdad es que para implementar la conexión con el servicio si necesitas hacer todo esto

  3. Jorge 24 de Marzo de 2011 at 11:38 #

    Hola Jesús, gracias por el post.
    Yo tengo un servicio hecho con axis2, y en la parte de seguridad lo tengo con usernametoken sobre https. desde axis2 tengo muy claro como consumirlo, pero tengo un cliente que quiere consumirlo desde jaxws y ahí ya me perdí. ellos usan netbeans y no saben si tienen que hacer todo esto o se puede hacer de manera gráfica. me podrías ayudar.?
    tienes mi correo: jorgeio at uci dot cu por si me quieres escribir. gracias.

  4. Sergio Fernandez Escobar 13 de Mayo de 2011 at 7:10 #

    Hola buenas noches disculpa no tendras el codigo por favor.

  5. Miguel Rodríguez 17 de Enero de 2014 at 19:12 #

    Buen ejemplo justo lo que estaba buscando.

  6. Dessie 12 de Septiembre de 2014 at 3:43 #

    I read a lot of interesting content here.
    Probably you spend a lot of time writing, i know how to save you a lot of time, there is an online tool that creates high quality,
    google friendly articles in minutes, just type in google – laranitas
    free content source

Dejar un comentario

*