Autenticación de servicios REST

Cuando nuestros servicios REST requieran autenticación de usuario deberemos hacerlo de manera segura, para ello es necesario establecer un protocolo para que todas las aplicaciones lo realicen de manera controlada y usando el mismo sistema. Actualmente esa normativa está en desarrollo apostando por el uso de OAuth para permitir compartir información del usuario que está logueado entre aplicaciones permitiendo proteger su información. No obstante y mientras este mecanismo se diseña definiremos otros aspectos de la normativa que sí están claramente definidos así cómo explicaremos un mecanismo alternativo de autenticación hasta que se implemente una solución definitiva.

A la hora de exponer la funcionalidad privada de nuestra web encapsularemos todas las rutas REST de nuestros servicios dentro del contexto private, así si nuestra aplicación oferta servicios públicos en:

    https://miaplicacion.um.es/miaplicacion/rest/v1.0/public/servicioX/metodoY

Los métodos privados se publicarán en:

    https://miaplicacion.um.es/miaplicacion/rest/v1.0/private/servicioX/metodoY

De esta manera podremos localizar, agrupar y encapsular fácilmente los conjuntos de servicios que ofertamos, tanto públicos como privados.

Es importante destacar que si tenemos una API privada para nuestro servicio REST, tendremos que tener un método de login, este método ha de ser público para que esté accesible para todos los usuarios.

    https://miaplicacion.um.es/miaplicacion/rest/v1.0/public/login

Éste método login será el encargado de autenticar el usuario, devolviendo un token temporal con el cual el usuario pueda interactuar con nuestra API.

También ofreceremos un método logout para asegurar la correcta desconexión del sistema por parte del cliente. No obstante como garantía adicional los token facilitados por nuestro método login tendrán un tiempo de vida máximo en caso de que no se usen.

Tal y como hemos visto en el apartado anterior, para permitir la autenticación en nuestros servicios deberemos suministrar un método login público para que los clientes puedan autenticarse en nuestra API. Ese método login deberá recibir el usuario y contraseña (y datos adicionales en caso de ser necesarios) y devolverá un token temporal al cliente con el cual podrá interactuar con el resto de la API.

La manera en la que el cliente debe mandar el login será haciendo uso de la cabecera authorization de http, indicando el usuario y contraseña correspondiente para poder hacer login:

   Authorization: <cadenaUsuarioPassword>

Donde <cadenaUsuarioPassword> será usuario:password codificados en base64.

Por su parte nuestro servicio REST deberá recuperar ese parámetro como parámetro de cabecera @HeaderParam, decodificarlo y obtener el usuario y password. Una vez obtenido el par usuario:password lanzar el método de validación que tengamos implantado en nuestra aplicación para hacer login.

Una vez pasado favorablemente el login deberemos generar el token de usuario que debe registrarse en base de datos con una marca de tiempo para poder gestionar la caducidad. A la hora de crear el token ha de asegurarse de que sea único para el par usuario:token.

Nuestro servicio devolverá al usuario un JSON de respuesta con el token generado tras el login.

Una vez el cliente tenga el token de autenticación, el uso de los servicios privados se realizará de manera similar al del login. El cliente deberá enviar en el parámetro de cabecera de autenticación el usuario:tokengenerado, junto con los parámetros que requiera el método al que se invoca.

En la parte del servidor para poder procesar de manera genérica la validación sin necesidad de, en cada método, hacer una llamada explícita a comprobar el token, deberemos crear un filtro implementando ContainerRequestFilter asociado al contexto rest/private que procese la petición recibida y lance el código que valida el token o mande una respuesta de error en caso de haber caducado o no ser válido.

De esta manera podremos abstraer la implementación de la parte privada de nuestros servicios REST que valida el token, evitando que se quede alguna petición sin autenticar. Este método de autenticación deberá comprobar no sólo que el token esté en base de datos para un usuario concreto, sino que no haya expirado. La manera más sencilla de gestionar la expiración de token es haciendo uso del campo de la marca de tiempo, teniendo un Job en base de datos que borre los token con una determinada antigüedad. Como cada vez que se autentique el token la fecha se actualizará garantizaremos que los tokens almacenados en la tabla serán los que no hayan expirado.

El proceso general de interacción una vez obtenido el token sería el indicado en el siguiente diagrama.

  • fdw2.0/fundeweb2.0/gt/rest/autenticacion_de_servicios_web_rest_jwt.txt
  • Última modificación: 25/04/2019 13:06
  • por PEDRO DELGADO YARZA