Guía de uso de Spring Security

Spring Security es un framework que proporciona autenticación, autorización y protección para aplicaciones Java (principalmente basadas en Spring). Es altamente personalizable tanto en su parte de autenticación como en el control de acceso para los usuarios ya que puede ser extendido fácilmente para cumplir los requisitos que se deseen. Dentro de las aplicaciones basadas en Spring, Spring Security es el estándar principal para todos la implementación de la seguridad de los mismos.

OAuth2

OAuth2 es un estándar que te permite crear flujos de autorización para nuestras aplicaciones. Está centrado en la simplicidad a la hora de otorgar autorizaciones específicas, permitiendo la autenticación segura de las APIs. 

El ejemplo a continuación muestra el flujo que sigue OAuth2 cuando un usuario no autenticado solicita un recurso de la aplicación: 

Spring Security ofrece soporte para implementar tu seguridad utilizando los flujos de OAuth 2.0.  Su implementación es tan sencilla como añadir la siguiente dependencia en el archivo «pom.xml»:

pom.xml
  
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-oauth2-client</artifactId> 
</dependency> 

Tendrás que definir también las siguientes variables dentro de tu fichero «yml» de configuración:

application.yml  

spring: 
        security: 
                oauth2: 
                        client: 
                                registration: 
                                       custom-client: 
                                             client-id: //Id del servidor de OAuth2 (Obligatorio) 
            			client-secret: //Secret del servidor de OAuth2 (Obligatorio) 
            			client-name: //Nombre del servidor de OAuth2 
           				scope: //Roles de acceso 
           			 	provider: //Nombre del proveedor (linea 16 de este fichero 'custom-provider') 
            			redirect-uri: //Url a la que se redirigirá al usuario tras una autenticacion y autorización correcta 
          			  	client-authentication-method: //Indica el tipo de autenticación del servidor (basic, post, none) 
        			   	authorization-grant-type: //Método por el que la aplicación obtiene un token de acceso (authorization_code, refresh_token...) 
provider: 
          		custom-provider: 
            		token-uri: //URL de obtencion del token 
            		authorization-uri: //URL de autorización de la aplicación 
            		user-info-uri: //URL de obtención de información del usuario 
            		user-name-attribute: //Nombre del campo con el nombre del usuario 

Seguidamente, añade la siguiente configuración en el archivo «SecurityConfig.java» de tu proyecto para crear el login

@Configuration 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 
  
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
        http.authorizeRequests() 
         .anyRequest().authenticated() 
         .and() 
         .oauth2Login(); 
    } 
} 

Filtros de seguridad

Spring Security tiene una serie de filtros de seguridad predeterminados a los cuales se le pueden añadir nuestros propios filtros personalizados en el punto de la cadena de filtros que queramos. 

Para ello, crearíamos una clase para nuestro filtro en «CustomFilter.java»: 

public class CustomFilter extends GenericFilterBean { 
  
    @Override 
    public void doFilter( 

      ServletRequest request,  
      ServletResponse response, 

      FilterChain chain) throws IOException, ServletException { 
        chain.doFilter(request, response); 
    } 
} 

Y posteriormente, en una clase de configuración «CustomWebSecurityConfigurerAdapter.java», añadie tu filtro en la posición que desees: 

@Configuration 

public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { 
  
    @Override 
    protected void configure(HttpSecurity http) throws Exception { 

        http.addFilterAfter( 
          new CustomFilter(), BasicAuthenticationFilter.class); 
    } 
} 

Aparte del método «addFilterBefore», existen también los siguientes: 

  • addFilterAfter(filter, class): añade el filtro después del filtro especificado. 
  • addFilterAt(filter, class): añade el filtro en la posición del filtro especificado. 
  • addFilter(filter): añade un filtro que debe ser una instancia o extender alguno de los filtros ya proporcionados por Spring Security. 

Protección de URLs

Dentro de la clase de configuración, podemos definir reglas en las cuales indicar que URLs de nuestra aplicación queremos que sean protegidas y a cuales se puede acceder sin autorización. 

Para ello podemos definir algo como lo del ejemplo a continuación en «CustomWebSecurityConfigurerAdapter.java»: 

 @Override 
 protected void configure(final HttpSecurity http) throws Exception { 

        http.authorizeRequests().antMatchers("/admin**").hasRole("ADMIN") 
        //Indicamos que para las URL que pertenezcan a /admin solo se pueda acceder si se tiene el rol de administrador 
        .antMatchers("/home").permitAll() 
        //Indicamos que para la URL de inicio pueda acceder todo el mundo 
        .anyRequest().authenticated() 
        //Indicamos que para el resto de URLs no indicadas anteriormente haya que estar autenticado  

Pre-Authorize

Además de poder añadir filtros de seguridad para las peticiones HTTP entrantes a tu aplicación, puedes añadir estas comprobaciones a nivel de método, de modo que se ejecuten cuando se llame a ese método en cuestión (principalmente los de los controllers). Es necesario que la aplicación tenga algún tipo de autenticación o se le administre un token a los métodos a los que se les quiera añadir esta capa de seguridad. 

Estas dos características no son excluyentes, de modo que los filtros de seguridad que tengas definidos se aplicarían y, tras haberlos pasado, se ejecutarían las comprobaciones de los Pre-Authorize

Para hacer uso de los Pre-Authorize hay que previamente añadir las siguientes anotaciones a la clase de configuración «CustomWebSecurityConfigurerAdapter.java»: 

@EnableGlobalMethodSecurity(prePostEnabled = true) 
@EnableWebSecurity 

Para indicar que métodos van a usar esta capa de seguridad, basta con marcarlos con la siguiente anotación en «RestController.java»: 

@PreAuthorize("hasRole('ADMIN')") 

Ese ejemplo indican que el usuario que ha hecho la petición debe tener el rol de administrador para poder acceder a ese recurso. También se podrían definir las siguientes condiciones: 

  • hasAnyRole(‘Rol1’, ‘Rol2’,…) : se indica la lista de roles que pueden acceder al recurso en cuestión. 
  • hasAuthority(‘Authority1’) : el usuario debe tener la autorización correspondiente para ese método.
  • hasAnyAuthority(‘Authority1′, Authority2’, etc.) : se indica una lista de las autorizaciones permitidas para ese método. 

PostAuthorize

Además del Pre-Authorize, existe el Post-Authorize el cual cumple la misma función pero añadiendo la capa de seguridad al retorno del método marcado por dicha anotación.

CSRF

Los ataques CSRF suelen ser usados para estafas por Internet. Los atacantes se adueñan de una sesión autorizada por el usuario para realizar sus estafas mediante solicitudes HTTP. 

Mediante Spring Security, puedes definir la seguridad para prevenir los ataques de tipo CSRF. Por defecto, la protección contra estos ataques viene por defecto activada; aun así, puede ser configurada en «Configuration.java»: 

@Override 
protected void configure(HttpSecurity http) throws Exception { 
    http 
      .csrf().disable(); 

} 

CORS

El intercambio de recursos de origen cruzado (CORS)  es un mecanismo para las peticiones HTTP en el cual, mediante cabeceras se permite que un usuario obtenga permiso para acceder a recursos desde un origen distinto al que pertenece el servidor. 

Para poder permitir estas peticiones dentro de tus microservicios, en tu clase de configuración puedes extender el filtro de CORS predeterminado de Spring Security en «Configuration.java»: 

@Bean 
public FilterRegistrationBean<CorsFilter> corsFilterOauth() { 

        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
        final CorsConfiguration config = new CorsConfiguration(); 

        config.setAllowCredentials(true); 
        config.addAllowedOrigin("*"); 
        config.addAllowedHeader("*"); 
        config.addAllowedMethod("*"); 

        source.registerCorsConfiguration("/**", config); 
        final FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source)); 
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE); 

        return bean; 
    } 

Como vemos, configurar Spring Security es bastante sencillo y ofrece varias opciones muy interesantes para tus proyectos.

Si os surge alguna duda, por favor dejadnos un comentario y os responderemos rápidamente.

Imagen de cabecera: Matthew Waring en Unsplash.

Autor

Deja una respuesta

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