...
Para realizar la comprobaciones en cada petición que llegue, podemos utilizar filtros que añadiremos a la configuración de seguridad de nuestra aplicación.
...
Filtro de autorización
Para comprobar el token en cada petición que se haga, tendremos un filtro de autorización. Un ejemplo, podría ser este:
...
De aquí, lo más importante, y lo que tendremos que implementar de acuerdo a las necesidades de nuestra aplicación es el método doFilterInternal(). En éste, inicialmente se comprueba que la petición es a un método privado (las demás no se filtrarán) con la función isPrivate definida más abajo. Después va la parte personalizada, en este caso se comprueba el token y se obtiene el siva id; ambas cosas están implementadas en la llamada a getSivaIdFromToken de expedientesService, que tenemos en nuestro proyecto y hemos añadido con @Autowired, de forma que si cualquiera de los dos pasos falla, se lanzará una excepción, que es la que se devolverá al frontend y será controlada en éste. Si todo es correcto, llamamos a filterChain.doFilter(...), que sirve para continuar al siguiente filtro, si hay otros definidos.
En el caso de que utilicemos login con cliente CAS, también incluiremos un filtro de autenticación, que verificará la identidad del usuario que realiza las peticiones. Tenemos el siguiente ejemplo:
| Bloque de código | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager
.getLogger( JwtAuthenticationFilter.class );
private final AuthenticationManager authenticationManager;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
super.setAuthenticationFailureHandler(new JwtAuthenticationFailureHandler());
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException {
log.info( "############ AUTHENTICATION: ATTEMTP" );
try {
final LoginUsuario userCredentials = new ObjectMapper().readValue(request.getInputStream(), LoginUsuario.class);
return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(
userCredentials.getEmail(), userCredentials.getPassword()));
} catch (final IOException e) {
return null;
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
Authentication authResult) throws IOException, ServletException {
log.info( "############ AUTHENTICATION: SUCCESS" );
final String token = TokenUtil.generaToken(authResult);
response.addHeader(HEADER_AUTHORIZATION_KEY, TOKEN_BEARER_PREFIX + " " + token);
}
} |
Podemos ver que además del constructor, implementamos los métodos attempAuthentication y successfulAuthentication en los que intentamos autenticar al usuario con sus credenciales y especificamos el comportamiento una vez se ha hecho la autenticación, respectivamente.
...
.
Este filtros tendremos que añadirlo en nuestra configuración de seguridad:
| Bloque de código | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| ||||||||||
/**
* Defino como Bean el authorization filter para que sea accedido desde los filtros ya que no estan en el mismo contexto
*/
@Bean
public JwtAuthorizationFilter jwtAuthorizationFilterBean() {
return new JwtAuthorizationFilter();
}
/**
* Proveedor de gestion de acceoss
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy( SessionCreationPolicy.STATELESS ) // configuro politica de
// sesion sin estado
.and().cors() // Aniado configuracion CORS por defecto
.and().csrf().disable()
.addFilterBefore( jwtAuthorizationFilterBean(), BasicAuthenticationFilter.class );
} |
...