domingo, 21 de noviembre de 2010

Autenticación en servicios web con CXF

En esta entrada voy a explicar los pasos necesarios para montar una capa de servicios web, en la que, para invocarlos, sea necesario enviar un usuario y contraseña en la cabecera de la petición (HTTP Basic Authentication).

Cómo ahora en el trabajo estoy utilizando Apache CXF, me voy centrar en este framework.

Lo primero de todo es incluir dentro de nuestro proyecto la siguiente clase: BasicAuthAuthorizationInterceptor.

Una vez tengamos la clase dentro de nuestro classpath, creamos un bean de spring sobre ella:











Como podemos apreciar, este bean esta pensado para que se le inyecte en la propiedad "users" un listado de todos los usuarios/contraseñas a los que se les permitirá invocar a los servicios web. Este comportamiento puede ser modificado muy fácilmente para que los usuarios y contraseñas que utilice no sean estos, sino que se obtengan de una base de datos o de algún fichero de propiedades.

Una vez que tenemos creado el interceptor, lo aplicamos a los endpoints de CXF que deseemos.


id="serviceEndpoint"
implementor="#service"
address="/ws/Service">







Y con esto ya está funcionando la validación en la capa de servicios web. Muy fácil de configurar :-)

Toda esta información la he sacado del siguiente enlace.

jueves, 18 de noviembre de 2010

Configurar CXF en proyecto con Hibernate

Recientemente he tenido que incorporar las librerías de CXF para exponer unos beans de Spring como servicios web. He seguido todos los datos que se explican en el sitio web del proyecto y aún así me estaba encontrando continuamente con un problema.

Los métodos que exponía como servicio web estaban devolviendo un objeto básico con sus getters/setters y al invocarlo me daba el siguiente error:


‘org.apache.cxf.interceptor.Fault: Marshalling Error: ReturnObject is not known to this context’.


Trás mucho indagar por internet vi la solución. Gracias sobre todo al siguiente enlace. Resulta que hay una incompatibilidad entre la versión de la librería ASM que usa Hibernate (1.5.3) y la que necesita CXF (2.2.3).

Las dependencias de mi proyecto están gestionadas con Maven, por lo que la solución fue sencilla: Poner una cláusula de exclusion en la dependencia de hibernate para que no se traiga ASM ni CGLIB, añadir una dependencia con CGLIB-NODEP y dejar que las dependencias de CXF se traigan exactamente la versión de ASM que necesitan.

En el pom.xml quedaría así:



org.hibernate
hibernate
3.2.5.ga
compile


asm
asm


asm
asm-attrs


cglib
cglib





cglib
cglib-nodep
2.1_3
compile



org.apache.cxf
cxf-rt-frontend-jaxws
${cxf.version}



org.apache.cxf
cxf-rt-transports-http
${cxf.version}



Una vez realizados estos cambios, el servicio web funcionó como un tiro :-D

martes, 16 de noviembre de 2010

Importar certificado en la máquina virtual

Si se desea realizar una conexión segura desde un cliente de java (Por ejemplo para invocar a un servicio web remoto mediante https) hay que realizar los siguientes pasos:

  • Obtener el certificado del servidor al que nos queremos conectar. Muchas veces se puede obtener desde el mismo navegador. Se puede exportar desde el firefox muy fácilmente.

  • Ejecutar el siguiente comando en la consola desde el directorio donde tengamos instalado el ejecutable keytool de la máquina virtual de java:


keytool -import -alias <Alias> -file <FICHERO_CERTIFICADO> -keystore <JRE_HOME>/jre/lib/security/cacerts

la contraseña por defecto es "changeit".

Si estamos utilizando el cliente de java desde una aplicación desplegada en un tomcat por ejemplo, será necesario reiniciarlo para que funcione correctamente.

Así de sencillo.