====== Autenticación con token en servicios REST ======
En esta wiki vamos a explicar el mecanismo de autenticación con token para poder incorporarlo a nuestros servicios REST. El mecanismo funciona interceptando las peticiones que hacen a nuestra aplicación lanzando automáticamente la autenticación de manera transparente aceptando o rechazando la petición según proceda. Paralelamente este mecanismo gestiona la creación y actualización de los token de usuario por lo que libera a los programadores de dicha tarea.
Este mecanismo tiene unas **precondiciones** que nuestro proyecto debe cumplir:
* Los servicios públicos deben estar contenidos en el path: http://miproyecto.um.es/miproyecto/vx.x/rest/public/servicioX
* Los servicios que requieran autenticación deben estar en: http://miproyecto.um.es/miproyecto/vx.x/rest/private/servicioX
* **NO** se debe crear ningún método de login, el servicio lo provee automáticamente en: http://miproyecto.um.es/miproyecto/rest/vx.x/public/login
===== Funcionamiento del servicio =====
El servicio de autenticación con token se basa en dos listener para las peticiones entrantes/salientes en los cuales se lleva a cabo la tarea de validación de usuario y/o token, aceptando o denegando la petición según proceda. De esta manera los desarrolladores no necesitan incluir validaciones explícitas en su código evitando olvidos a la hora de comprobar los accesos. Es importante cumplir las precondiciones indicadas en el apartado anterior para asegurar el buen funcionamiento del sistema.
==== Envío de cabeceras ====
Todas las peticiones que se hagan al servicio para la parte privada o el login deberán incluir la cabecera de autorización **Authorization**.
En dicha cabecera deberán incluirse:
* Si queremos hacer login: **usuario:contraseña**, codificado en Base64
* Si accedemos aun método private: **usuario:token**, condificado en Base64
==== Listener de peticiones ====
El listener de peticiones escucha todas las peticiones entrantes y las respectivas respuestas actuando para cada petición rest recibida. Cada vez que se accede a una ruta que esté en el path ../private/.. el listener obtendrá la **cabecera de autenticación** y realizará las comprobaciones oportunas según el caso para comprobar si el solicitante tiene acceso o no al método.
Cuando queramos hacer login, nuestra aplicación dispondrá por defecto de un método http://miproyecto.um.es/miproyecto/rest/vx.x/public/login en el cual el usuario podrá loguearse con su usuario y contreña. **Este método no hay que crearlo en nuestro servicio REST** ya que está incluido por defecto. El cliente mandará usuario:password codificado en Base64 en la cabecera de autenticación y el listener de peticiones tras detectar que se intenta acceder a la url de login lanzará la autenticación del usuario (que deberemos implementar). En caso existoso se creará un token para dicho usuario, borrando los existentes y se devolverá codificado en Base64.
{{ :fdw2.0:fundeweb2.0:gt:rest:restlogin.png?1100 |}}
Cuando queramos acceder a un servicio dentro del path ../private/.. deberemos mandar usuario:token, codificado en Base64. En este caso el servicio recuperará el token, comprobará que existe y no está caducado y, en caso afirmativo, actualizará el tiempo de vida del token y ejecutará la petición que el usuario había solicitado.
{{ :fdw2.0:fundeweb2.0:gt:rest:tokenprivate.png?1100 |}}
En caso de tener una autenticación diferente de usuaripo:password, podremos extender la clase encargada de autenticar para modificar ese comportamiento.
==== Estructura de clases ====
Las clases que vienen creadas por defecto en el módulo de autenticaciónn REST son las entidades, DAS y servicios necesarios para gestionar los usuarios y los token. A su vez, se incluye una clase que controla la autenticación, la cual puede ser sobrescrita si deseamos modificar la autenticación por defecto.
Ésta infraestructura es utilizada por dos filtros: RestRequestFilter y RestResponseFilter
{{ :fdw2.0:fundeweb2.0:gt:rest:resauthmodel.png?900 |}}
**RestRequestFilter**: Filtro que analizará todas las peticiones a las rutas ../private/.. y comprobará si el usuario que solicita el servicio tiene un token válido para ejecutarlo.
**RestResponseFilter**: Filtro que analiza todas las peticiones a public/login y lanza la autenticación.
**RestAuthenticationProvider**: Clase encargada de gestionar la autenticación tanto por usuario:password, como usuario:token. Puede ser sobrescrita para cambiar la manera de autenticarse.
**ServicioAutorizacionRest**: Servicio encargado de cargar y persistir los datos relativo a la autenticación y generar o limpiar los token de usuario.
===== Implementación del servicio =====
==== Creación de base de datos ====
La primera acción que debemos llevar a cabo es ampliar nuestro esquema de base de datos, para ello deberemos crear dos tablas para la gestión de usuarios y tokens de nuestra aplicación:
* **REST_USUARIOS**: Guardará una relación de usuario/password habilitados para consultar los servicios REST de nuestra aplicación.
* **REST_USUARIO_TOKEN**: Guardará una relación de los token creados en la aplicación y los usuarios a los que pertenecen.
Este esquema de tablas puede crearse a partir del {{ :fdw2.0:fundeweb2.0:gt:rest:restauthschema_.txt |script de creación}}. El tiempo de duración de sesión del token se establece como valor por defecto en la tabla REST_USUARIO_TOKEN en milisegundos (por defecto son 5 minutos).
En la tabla REST_USUARIOS los password se guardarán encriptados. El código fuente del servicio incorpora el algoritmo de encriptación a falta de especificar la clave de cifrado que debe ser configurada por aplicación. Para las pruebas, dentro del paquete "util" del código fuente se ha añadido una clase para encriptar un password dado.
Los fuentes para la autenticación rest los tienes en {{ :fdw2.0:fundeweb2.0:gt:rest:src.zip |este empaquetado}}.
==== Configuración ====
Por último, una vez incorporado los fuentes a nuestro proyecto, sólo quedaría configurar los filtros para que se lancen en todas las peticiones sobre la url http://miaplicacion.um.es/miaplicacion/rest para ello debemos añadir en el fichero **web.xml** el siguiente código
En el nombre de los paquetes cambiar "miapliacion" por el nombre del proyecto
Donde debemos indicar dónde se encuentran las clases que harán de filtro. Para **aplicaciones FundeWeb 2.0**.
com.sun.jersey.spi.container.ContainerRequestFilters
es.um.atica.miaplicacion.security.rest.filter.RestRequestFilter
com.sun.jersey.spi.container.ContainerResponseFilters
es.um.atica.miaplicacion.security.rest.filter.RestResponseFilter
\\
\\
Este paso solo es necesario en **aplicaciones FundeWeb 1.5 migradas a Weblogic 12.2**. Tenemos que abrir el fichero //cxf-beans.xml// y añadimos los siguientes beans al final del fichero:
...
Para poder utilizarlos, tenemos que añadirlos a un elemento //// o ////.
...
...
Hay que tener encuenta que //problemContainerRequestFilter// tiene que ser el primer //ContainerRequestFilter// declarado y que //problemContainerResponseFilter// tiene que ser el último //ContainerResponseFilter// declarado.