WSS (Web Service Security) – Autenticación por usuario y contraseña
Índice de contenido
- Introducción.
- Entorno.
- Instalación de Axis2.
- Creación del servicio.
- Creación del cliente
- Conclusiones
Introducción
En este tutorial vamos a ver como crear un servicio web seguro con autenticación mediante usuario y contraseña.
En primer lugar tenemos que tener en cuenta que WS-Security no es un nuevo tipo de servicios web ni de
seguridad. WS-Security define cómo utilizar los tokens de seguridad, XML Signature y Xml Encryption en los
mensajes SOAP para proporcionar autenticación, confidencialidad e integridad a los Servicios Web.
En el caso que nos ocupa, vamos a centrarnos únicamente en la autenticación del usuario mediante un token de usuario y contraseña.
Debemos saber que en WS-Security también existen otros tipos de autenticación basados en certificados X509, tickets de Kerberos, etc.
que no vamos a ver en este tutorial.
Entorno
El tutorial está escrito usando el siguiente entorno:
-
Hardware: Portatil Samsung R70 ( Intel(R) Core(TM)2 Duo 2,5Ghz, 2046 MB RAM, 232 Gb HD)
-
Sistema Operativo: Windows Vista Home Premium
-
Máquina Virtual Java: JDK 1.5.0_14 de Sun Microsystems (http://java.sun.com/javase/downloads/index_jdk5.jsp
-
Servidor Web: Apache Tomcat 6.0.16 (http://tomcat.apache.org/download-60.cgi
-
Motor de servicios web Apache Axis2 1.4.1 (http://ws.apache.org/axis2/download/1_4_1/download.cgi) con en módulo de Rampart 1.4 http://ws.apache.org/rampart/download/1.4/download.cgi
-
IDE Eclipse 3.3 (Europa) (http://www.eclipse.org/downloads/)
Instalación de Axis2.
En este tutorial de nuestro compañero
Iván nos explica la creación de servicios web con Axis2,
por lo que toda la preparación del entorno es la misma, así que sólamente vamos a recordar brévemente la instalación del módulo web de Axis2
que nos va a servir como motor de servicios web.
Nos descargarmos la distribución en WAR de Axis2 que viene comprimida, y lo único que tenemos que hacer es descomprimir el fichero «axis2-1.4.1-war.zip»
y copiar en el directorio «webapps» de nuestro tomcat el fichero axis2.war. Al arrancar el tomcat desplegará esta aplicación y ya tendremos nuestro motor de servicios
web funcionando.
Para comprobar que todo ha ido correctamente podemos ir a http://localhost:8080/axis2/axis2-web/HappyAxis.jsp y comprobar que todo funciona correctamente.
NOTA: Si teneís instalado algún antivirus, es posible que os corte la comunicación de las peticiones a los servicios web. No se exáctamente porqué, pero en mi caso las peticiones http a páginas web
funcionaban correctamente, pero las peticiones a servicios web no lo hacían, por lo que tuve que cambiar la configuración del antivirus. Se puede detectar si en la página «HappyAxis» os sale un mensaje como este:
O si ejecutáis un cliente java podéis obtener un error como éste:
1 2 3 |
org.apache.axis2.AxisFault: com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog at [row,col {unknown-source}]: [1,0] ... |
Ya sabéis, cosas de los antivirus :(.
Hasta aquí lo que hemos conseguido es tener la instalación de servicios web normal, pero nos falta incluirle las extensiones que soporten WS-Security. Para esto nos vamos ha descargar
la implementación a href=»http://ws.apache.org/rampart/»>Apache Rampart, concretamente la versión 1.4. Este módulo
es el módulo de seguridad para axis2, y en su página podéis encontrar toda la especificación del mismo.
Para instalar el módulo de Rampart, descomprimimos el fichero ZIP que nos hemos descargado, y lo único que tenemos que hacer es copiarnos todas las librerías (JAR’s) del directorio «lib»
de la distribución de Rampart al directorio «WEB-INF/lib» de nuestra instalación de Axis2 y los ficheros del directorio «modules» de la distribución de Rampart al directorio «WEB-INF/modules»
de la instalación de Axis2.
Ahora ya tenemos instalado nuestro motor de servicios web con el soporte de seguridad definido en WS-Security.
Creación del servicio.
Para crear el servicio vamos a crearnos un nuevo proyecto de Maven, de esta forma podemos aprovechar no sólo la gestión de dependencias, también utilizaremos el plugin de empaquetamiento
para generar archivos «.aar» (Axis ARchive, equivalente a los «.jar»). Si quereís ver como se instala el plugin de Maven (Q4E) para eclipse podéis ver
este tutorial de nuestro compañero Alejandro.
Creamos un nuevo proyecto de Maven para el servicio web, seleccionamos
![]() |
![]() |
![]() |
El plugin nos generará la siguiente estructura, donde vamos a eliminar las clases «App.java» y «AppTest.java» que nos crea.
Modicamos el pom.xml
Ahora vamos a modificar el fichero «pom.xml» para utilizar el plugin «axis2-aar-maven-plugin».
Con este plugin vamos a empaquetar el proyecto directamente como un fichero «aar» que podremos desplegar como servicio web directamente. Podéis ver cómo indicamos que el fichero «services.xml»
que crearemos en el directorio «src/main/config» lo incluya en el directorio «META-INF» y servira como descriptor del servicio para Axis2.
También crearemos la dependencia con WSS4J, necesaria para incluir la seguridad a nuestro servicio web.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.autentia.wss.usertoken</groupId> <artifactId>WSSUserTokenService</artifactId> <packaging>aar</packaging> <version>1.0-SNAPSHOT</version> <name>WSSUserTokenService</name> <url>http://maven.apache.org</url> <build> <plugins> <plugin> <groupId>org.apache.axis2</groupId> <artifactId>axis2-aar-maven-plugin</artifactId> <version>1.4.1</version> <extensions>true</extensions> <configuration> <fileSets> <fileSet> <directory> src/main/config/ </directory> <outputDirectory>META-INF</outputDirectory> <includes> <include>services.xml</include> </includes> </fileSet> </fileSets> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.apache.ws.security</groupId> <artifactId>wss4j</artifactId> <version>1.5.4</version> <scope>provided</scope> </dependency> </dependencies> </project> |
Clase del servicio
Ahora vamos a crear la clase que va a proporcionar el servicio. En este caso es un servicio de echo «Echo.java»,
que como véis no tiene ningún misterio, donde indicaremos la configuración de seguridad será en el fichero descriptor
del servicio.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package com.autentia.wss.usertoken.service; /** * <p> * Echo.java <br/> Clase que implementa la logica de nuestro web service * </p> */ public class Echo { /** * Metodo que implementa la funcionalidad de saludo * * @param nombre Nombre de la persona que invoca el servicio * @return Cadena de saludo */ public String saludar(String nombre) { return "Hola " + nombre; } /** * Metodo que implementa la funcionalidad de despedida * * @param nombre Nombre de la persona que invoca el servicio * @return Cadena de despedida */ public String despedir(String nombre) { return "Adios " + nombre; } } |
Descriptor del servicio
Para desplegar el servicio en Axis2, nos creamos un fichero descriptor del mismo. En este caso seguimos la estructura que hemos indicado en nuestro fichero «pom.xml»,
y creamos el fichero «services.xml» en el directorio «src/main/config».
En este fichero, además de descripbir el servicio, vamos a incluir una política de seguridad para comprobar la autenticación de quién está llamando al servicio.
Esto lo hacemos en dos partes, una indicando la configuración de seguridad de autenticación mediante usuario y contraseña. Y otra configurando adecuadamente el módulo de Rampart,
que hemos visto que va a ser el encargado de resolver la seguridad de nuestro servicio web.
En la configuración de Rampart, indicaremos la clase responsable de comprobar los usuarios y contraseñas con el elemento «passwordCallBackClass».
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<service> <description> Web service que emite un saludo o una despedida con autenticación de usuario </description> <messageReceivers> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" /> </messageReceivers> <parameter name="ServiceClass"> com.autentia.wss.usertoken.service.Echo </parameter> <operation name="saludar" mep="http://www.w3.org/2004/08/wsdl/in-out" /> <operation name="despedir" mep="http://www.w3.org/2004/08/wsdl/in-out" /> <module ref="rampart" /> <wsp:Policy wsu:Id="UserToken" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> <wsp:ExactlyOne> <wsp:All> <sp:SignedSupportingTokens xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy"> <wsp:Policy> <sp:UsernameToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient" /> </wsp:Policy> </sp:SignedSupportingTokens> <ramp:RampartConfig xmlns:ramp="http://ws.apache.org/rampart/policy"> <ramp:passwordCallbackClass> com.autentia.wss.usertoken.service.PWCBHandler </ramp:passwordCallbackClass> </ramp:RampartConfig> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> </service> |
Clase de comprobación de usuario y contraseña
Lo único que nos queda por implementar en nuestro servicio es la clase que comprueba el usuario y contraseña de las peticiones de servicio.
Nos creamo la clase «com.autentia.wss.usertoken.service.PWCBHandler» que hemos configurado en el descriptor del servicio para que se encargue de
dicha tarea. Esta clase debe heredar de «javax.security.auth.callback.CallbackHandler» y el tipo de «callback» que va a procesar es del tipo «org.apache.ws.security.WSPasswordCallback».
El código de nuestra clase es:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
package com.autentia.wss.usertoken.service; import org.apache.ws.security.WSPasswordCallback; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import java.io.IOException; public class PWCBHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { //Autenticación del usuario y contraseña WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i]; //comprobaciones de usuario y contraseña para acceso al servicio if(pwcb.getIdentifer().equals("autentia") && pwcb.getPassword().equals("password")) { //autenticación con éxito return; } else { throw new UnsupportedCallbackException(callbacks[i], "fallo de autenticación"); } } } } |
Despliegue del servicio
Para desplegar el servicio primero empaquetamos ejecutando el siguiente comando de Maven en la consola, situándonos en el directorio raíz del proyecto.
1 |
mvn package |
Esto nos generará el fichero «WSSUserTokenService-1.0-SNAPSHOT.aar» en el directorio «target» de nuestro proyecto. Ahora sólo nos queda copiar dicho fichero
al directorio «WEB-INF/services» de la instalación de Axis2 y se desplegará nuestro servicio que podremos comprobar en la administración web de Axis2, y vemos que tiene vinculado el módulo de Rampart.
Creación del cliente.
Para crear el el cliente, nos creamos otro proyecto de Maven igual que hicimos con el servicio, donde vamos a cambiar el nombre (lógicamente) por «WSSUserTokenClient» y el paquete de las clases por «com.autentia.wss.usertoken.client».
Modificación del pom.xml
Igual que hicimos antes, lo primero que tenemos que hacer es modificar el fichero «pom.xml» del proyecto.
En este caso vamo a realizar muchos más cambios, para poder aprovechar las distintas características de distintos plugins,
entre las que debemos destacar (para el caso que nos ocupa) la generación automática de las clases clientes del servicio
para ser utilizadas directamente por nuestro cliente. También crearemos las dependencias necesarias, en este caso dependecias
con los distintos módulos de Rampart, para la seguridad en los servicios web.
El fichero «pom.xml» queda de la siguiente forma:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.autentia.wss.usertoken</groupId> <artifactId>WSSUserTokenClient</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>WSSUserTokenClient</name> <url>http://maven.apache.org</url> <build> <plugins> <plugin> <!-- Genera automáticamente las clases clientes del servicio para ser utilizadas en nuestro proyecto --> <groupId>org.apache.axis2</groupId> <artifactId>axis2-wsdl2code-maven-plugin</artifactId> <version>1.4.1</version> <executions> <execution> <goals> <goal>wsdl2code</goal> </goals> </execution> </executions> <configuration> <packageName> com.autentia.wss.usertoken.client </packageName> <wsdlFile> http://localhost:8080/axis2/services/WSSUserTokenService-1.0-SNAPSHOT?wsdl </wsdlFile> </configuration> </plugin> <plugin> <!-- Genera un fichero .jar ejecutable incluyendo el classpath a las dependencias --> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <archive> <manifest> <mainClass> com.autentia.wss.usertoken.client.EchoClient </mainClass> <packageName> com.autentia.wss.usertoken.client </packageName> <addClasspath>true</addClasspath> <classpathPrefix>lib/</classpathPrefix> </manifest> <manifestEntries> <mode>development</mode> <url>${pom.url}</url> </manifestEntries> </archive> </configuration> </plugin> <plugin> <!-- Copia las dependencias al directorio "lib" para tenerlas ya disponible para la ejecución del empaquetado final--> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory> ${project.build.directory}/lib </outputDirectory> <includeScope>runtime</includeScope> <overWriteIfNewer>true</overWriteIfNewer> </configuration> </execution> </executions> </plugin> <plugin> <!-- copia los recursos necesarios al directorio destino para que se pueda ejecutar el .jar generado directamente --> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>copy-resources</id> <phase>validate</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory> ${project.build.directory}/modules </outputDirectory> <resources> <resource> <directory> modules </directory> </resource> </resources> </configuration> </execution> </executions> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.4</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.rampart</groupId> <artifactId>rampart-core</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.apache.rampart</groupId> <artifactId>rampart-trust</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.apache.rampart</groupId> <artifactId>rampart-policy</artifactId> <version>1.4</version> </dependency> </dependencies> </project> |
Creación de la clase cliente
Antes de nada, para poder crear nuestra clase cliente, tenemos que generar las clases clientes para acceder al servicio,
esto lo hacemos ejecutando el siguiente comando de Maven la consola, situándonos en el directorio raíz de nuestro proyecto:
1 |
mvn wsdl2code:wsdl2code |
El código nos lo ha generado en el directorio «target/generated-sources/axis2/wsdl2code/src», por lo que en nuestro proyecto de
eclipse le debemos indicar que dicho directorio es un directorio de código fuente. Esto lo hacemos en las propiedades de nuestro proyecto.
Ahora ya podemos crear nuestra clase cliente «EchoClient.java» que tendrá el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
package com.autentia.wss.usertoken.client; import java.rmi.RemoteException; import org.apache.axis2.AxisFault; import org.apache.axis2.client.Options; import org.apache.axis2.client.ServiceClient; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import com.autentia.wss.usertoken.client.WSSUserTokenService10SNAPSHOTStub.Despedir; import com.autentia.wss.usertoken.client.WSSUserTokenService10SNAPSHOTStub.DespedirResponse; import com.autentia.wss.usertoken.client.WSSUserTokenService10SNAPSHOTStub.Saludar; import com.autentia.wss.usertoken.client.WSSUserTokenService10SNAPSHOTStub.SaludarResponse; /** * <p> * EchoClient.java <br/> Clase que prueba la invocacion a nuestro web service de * echo * </p> */ public class EchoClient { private String user; private String password; public String getUser() { return user; } public void setUser(String user) { this.user = user; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public EchoClient(String user, String password){ this.setUser(user); this.setPassword(password); } /** * Metodo principal de la clase * * @param args */ public static void main(String[] args) { EchoClient client = new EchoClient("autentia","password"); try { System.out.println(client.callServiceSaludar("Borja")); System.out.println(client.callServiceDespedir("Borja")); } catch (AxisFault e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public String callServiceSaludar(String name) throws AxisFault,RemoteException { /* * Utilizamos el stub generado a partir del wsdl que logran establecer * la conexion con el web service proveedor. */ WSSUserTokenService10SNAPSHOTStub stub =getStub(); Saludar saludar = new Saludar(); saludar.setNombre(name); SaludarResponse result = stub.saludar(saludar); return result.get_return(); } public String callServiceDespedir(String name) throws AxisFault,RemoteException{ /* * Utilizamos el stub generado a partir del wsdl que logran establecer * la conexion con el web service proveedor. */ WSSUserTokenService10SNAPSHOTStub stub =getStub(); Despedir despedir = new Despedir(); despedir.setNombre(name); DespedirResponse result = stub.despedir(despedir); return result.get_return(); } private WSSUserTokenService10SNAPSHOTStub getStub() throws AxisFault { ConfigurationContext ctx; //el directorio que le pasamos a la configuración debe contener un directorio //con nombre "modules" donde estarán los módulos de rampart "rampart-1.4" y "rahas-1.4" ctx = ConfigurationContextFactory .createConfigurationContextFromFileSystem(".", null); //indicamos la URL de punto de entrada a nuestro servicio WSSUserTokenService10SNAPSHOTStub stub = new WSSUserTokenService10SNAPSHOTStub( ctx, "http://localhost:8080/axis2/services/WSSUserTokenService-1.0-SNAPSHOT"); ServiceClient sc = stub._getServiceClient(); //vinculamos el módulo de rampart sc.engageModule("rampart"); Options options = sc.getOptions(); //indicamos usuario y contraseña options.setUserName(this.getUser()); options.setPassword(this.getPassword()); return stub; } } |
Módulos de Rampart
Como podemos ver en el código fuente de la clase, vinculamos a la petición el módulo de Rampart;
para que esto funcione correctamente, cuando creamos el contexto de Rampart le pasamos como parámetro el «path»
del directorio padre que contiene un directorio con nombre «modules» donde se encuentran los módulos «rampart-1.4» y «rahas-1.4».
En nuestro caso nos hemos creado un directorio «modules» en nuestro proyecto, donde hemos copiado dichos módulos.
Pruebas unitarias
Para comprobar que nuestro cliente funciona correctamente vamos a crearnos una clase de pruebas unitarias con JUnit para probar dicho funcionamiento.
Nuestra clase de prueba la ubicaremos dentro del directorio destinado para las pruebas «src/test/java», para que luego no se incluya en el JAR que generemos.
La clase de prueba «TestEcho.java» tiene el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
package com.autentia.wss.usertoken.client; import java.rmi.RemoteException; import junit.framework.Assert; import junit.framework.TestCase; import org.apache.axis2.AxisFault; /** * <p> * TestEcho.java <br/> Clase que prueba la invocacion a nuestro web service de * echo * </p> */ public class TestEcho extends TestCase { /** * Probamos el servicio saludar */ public static void testEchoSaludar() { EchoClient client = new EchoClient("autentia", "password"); try { Assert.assertEquals("Hola Borja", client .callServiceSaludar("Borja")); } catch (AxisFault e) { Assert.fail(e.toString()); } catch (RemoteException e) { Assert.fail(e.toString()); } } /** * Probamos el servicio despedir */ public static void testEchoDespedir() { EchoClient client = new EchoClient("autentia", "password"); try { Assert.assertEquals("Adios Borja", client .callServiceDespedir("Borja")); } catch (AxisFault e) { Assert.fail(e.toString()); } catch (RemoteException e) { Assert.fail(e.toString()); } } /** * Probamos el servicio saludar con un usuario incorrecto */ public static void testEchoBadUserSaludar() { EchoClient client = new EchoClient("otro", "password"); try { client.callServiceSaludar("Borja"); } catch (AxisFault e) { // si es porque no se a podido autenticar el usuario el test es // correcto Assert .assertEquals(e.getMessage(), "The security token could not be authenticated or authorized"); } catch (RemoteException e) { Assert.fail(e.getMessage()); } } /** * Probamos el servicio despedir con un usuario incorrecto */ public static void testEchoBadUserDespedir() { EchoClient client = new EchoClient("otro", "password"); try { client.callServiceDespedir("Borja"); } catch (AxisFault e) { // si es porque no se a podido autenticar el usuario el test es // correcto Assert .assertEquals(e.getMessage(), "The security token could not be authenticated or authorized"); } catch (RemoteException e) { Assert.fail(e.getMessage()); } } } |
Para ejecutar los tests que hemos programado, pulsamos sobre la clase «TestEcho.java»
con el botón derecho y seleccionamos «Run as –> JUnit Test», y podemos ver el resultado de la ejecución.
Empaquetando y ejecutando el cliente
Gracias a las pruebas unitarias, podemos asegurarnos que nuestro cliente está funcionando, por lo que podemos
generar un JAR que se ejecute directamente; esto lo hacemos ejecutando el siguiente comando de Maven
en la consola, situándonos en el directorio raíz de nuestro proyecto.
1 |
mvn package |
Esto nos genera el fichero «WSSUserTokenClient-1.0-SNAPSHOT.jar» en el directorio «target» de nuestro proyecto,
y también nos ha copiado todos los módulos de Rampart en en directorio «target/modules» y los JAR’s de todas las dependencias
en el directorio «target/lib». De esta forma, si abrimos una consola y vamos al directorio «target» de nuestro proyecto, podemos ejecutar
directamente nuestro cliente con el comando:
1 |
java -jar WSSUserTokenClient-1.0-SNAPSHOT.jar |
Conclusiones
Como podéis ver el módulo Rampart para Axis2 nos proporciona la implementación necesaria para WS-Security, y que combinando varias tecnologías
(Axis2, Maven, Rampart, JUnit) podemos generar y probar, en este caso servicios web seguros de un modo relativamente sencillo.
Un saludo.
Borja Lázaro de Rafael.
Hola buenas. he seguido el tutorial pero a la hora de crear el paquete del servicio con mvn package (parate del servidor) me da BUILD ERROR: Internal error executing goal \\\’org.aache.axis2-aar-maven-plugin:1.4.1:aar\\\’ Unable to load the mojo \\\’org.apache.axis2-aar-maven-plugin:1.4.1:aar\\\’ in the plugin \\\’org.apache.axis2-aar-maven-plugin\\\’. A required class is missing: org/apache/maven/archiver/MavenArchiveConfiguration.
Alguna sugerencia o idea, gracias de antemano.
El ejemplo me genera errores por problemas de configuración del POM, seria interesante tener al alcance el Código Fuente.
Saludos,
Marcelo
Esta muy bien y me ha ayudado mucho. Solo una puntualización al crear la clase cliente:
\\\»mvn wsdl2code:wsdl2code\\\» no me funcionó y usé \\\»mvn axis2-wsdl2code:wsdl2code\\\» que fue perfectamente.
Excelente, eso si faltan algunos detalles como indicar que el comando de generación de código es: mvn axis2-wsdl2code:wsdl2code y no mvn wsdl2code:wsdl2code y que faltan el package bouncycastle y backport-util-concurrent para los test, pero aún así aparece el error en el header, en mi caso almenos, de todas formas hay una clase (ReadWriteLock) que me esta jodiendo…. alguna idea??
confimado el ejemplo está MALO!!!
falta una bibliotecade apache en el servidor backport-util-concurrent-3.1.jar
y listo!!!
Gracias por los comentarios, los cambios que has necesitado hacer para que te funcionase seguramente se deben a que el tutorial lo hice hace más de dos años, y en este tiempo se han cambiado versiones y datos de configuración.
En cualquier caso, espero que os siga sirviendo como punto de partida.
No mamen, claro que funciona, solo tenia un pequeño error en la generación de las clases Java desde el WSDL pero en el comentario de bogoa666 dice cual es el comando que se debe de ejecutar en la consola del maven. Lo demás que pueda parecer error solo se soluciona con \\\»Investigación\\\» investiguen huevones!!!