Securización de un proyecto Spring Boot

Securización de un proyecto Spring Boot

Este artículo continua la serie iniciada en el primer artículo.

En este artículo vamos a presentar la implementación de la securización en la aplicación. Para ello, explicaremos cómo está implementada la autenticación y autorización de usuarios tanto en la parte web como en el API.
Antes de nada, señalar cuál es el comportamiento deseado e implementado:

  1. Web: existe una parte pública y otra privada para la cual es necesario estar autenticado
    1. Parte pública: únicamente la página para mostrar la versión de la aplicación
    2. Parte privada: un listado con los usuarios existentes. Para acceder a la parte privada es necesario autenticarse con un usuario a través de la página de login y, para ver el listado, es estrictamente necesario que sea un usuario con rol ADMIN
  2. API: igual que en la web, existe una parte pública y otra privada.
    1. Parte pública: hay algunas partes públicas del API como la petición para recuperar la versión de la aplicación, o una petición de test.
    2. Parte privada: el API tiene partes privadas y, para acceder a ellas, es necesario estar autenticado a través del formulario de login del API.
      1. Usuario: es la parte del API para la cual hay que estar autenticado con un usuario con rol USER
      2. Administrador: es la parte del API para la cual hay que estar autenticado con un usuario con rol ADMIN

Spring Security

Para implementar la securización de la aplicación utilizamos Spring Security. Para definir el cómo tenemos dos ficheros de configuración muy relevantes para cada una de las partes de la aplicación:

  1. Securización de la web: fichero WebSecurityConfig
  2. Securización del API: fichero ApiSecurityConfig

Recomiendo echarle un vistazo y comparar ambos ficheros, aunque adelanto que lo más relevante me parecen las líneas:

.antMatchers(WebURL.ADMIN+"/**").hasAnyAuthority(UserDetailsService.AUTHORITY_ADMIN)

donde se define qué rol (authority, en realidad, aunque hay una relación entre ambos definida en el servicio de Usuarios) es necesario poseer para acceder a cada uno de los recursos (en este caso a la parte de administración de la web).

Spring Security también nos ofrece herramientas para utilizar en la vista. De esta manera, podemos utilizar, como hacemos en el menú de la aplicación, cosas como:


Ahí, podemos ver diferentes funciones de las que se hacen uso, destacando sec:authorize, que sirve para mostrar o no un elemento dependiendo de, en este caso, un authority del usuario. Ojo, aquí definimos únicamente si el usuario puede ver en enlace o no, pero es responsabilidad del WebSecurityConfig definir si puede acceder o no al recurso.

Token JWT

La securización del API es basada en un token al portador (bearer token) JWT. De esta manera, para acceder a las partes privadas del API deberemos enviar una cabecera HTTP (Authorization) conteniendo el token que demuestre pertenecer a un usuario con los roles requeridos por el recurso.

Ejemplo de petición con autenticación:

curl --location --request GET 'http://localhost:8080/application-4.0.5/api/user/stories/2' \
--header 'Content-Type: application/json' \
--header 'Accept: ' \
--header 'Authorization: Bearer _MY_TOKEN_'

Para las peticiones del API públicas, por el contrario, no es necesario enviar la autorización.

Pero, ¿de dónde obtenemos el token? El token lo obtenemos a partir del login del usuario en el API, a través de la petición:

curl --location --request POST 'http://localhost:8080/application-4.0.5/api/auth/login' \
--header 'Content-Type: application/json' \
--header 'Accept: ' \
--header 'Content-Type: application/json' \
--data-raw '{
"username": "john",
"password": "doe"
}'

Lo cual nos devuelve, entre otras cosas, el token anterior (access_token) y otro token (refresh_token) para obtener nuevos access_token a medida que estos vayan caducando.

Para profundizar en esto, recomiendo echar un vistazo:

  1. AuthRequestFilter, donde se autentica al usuario del API en base a la cabecera comentada y su valor
  2. JwtTokenUtil: donde se generan tokens con la información necesaria y se obtiene información a partir de tokens.

Imagen principal: Photo by chris panas on Unsplash

Publicado en junio 25, 2020

,

,

,

,

,

Un comentario en Securización de un proyecto Spring Boot

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

« »