Configuración del Servidor de Recursos en OAuth con Spring Security

La anotación @EnableResourceServer se aplica a una clase de configuración @Configuration. La configuración se realiza mediante el objeto ResourceServerConfigurer. Una forma común es extender ResourceServerConfigurerAdapter y sobrescribir sus métodos. A continuación, se detallan las propiedades configurables.

Configuración de ResourceServerSecurityConfigurer:

  • tokenServices: Una instancia de ResourceServerTokenServices para implementar el servicio de tokens.
  • tokenStore: Una instancia de TokenStore para especificar el acceso a los tokens. Es opcional cuando se configura tokenServices.
  • resourceId: El identificador (ID) de este servicio de recursos. Aunque es opcional, se recomienda establecerlo y validarlo en el servidor de autorización.
  • Otras propiedades extendidas, como tokenExtractor (extractor de tokens) para obtener el token de la solicitud.

Confgiuración de HttpSecurity: Similar a la configuración de Spring Security estándar.

  • Definir los emparejadores de solicitudes para establecer las rutas de recursos protegidas. Por defecto, se protege toda la ruta del servicio de recursos.
  • Establecer reglas de acceso para los recursos protegidos mediante http.authorizeRequests().
  • Configurar reglas de protección de permisos personalizadas adicionales a través de HttpSecurity.

Ejemplo de configuración:

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class ResourceServerSecurity extends ResourceServerConfigurerAdapter {

    private static final String IDENTIFICADOR_RECURSO = "mi_aplicacion";

    @Autowired
    private TokenStore almacenDeTokens;

    @Override
    public void configure(ResourceServerSecurityConfigurer config) {
        config.resourceId(IDENTIFICADOR_RECURSO)
                .tokenServices(obtenerServicioDeTokens())
                .stateless(true);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/**").access("#oauth2.hasScope('acceso_completo')")
            .and().csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }

    @Bean
    @Primary
    public ResourceServerTokenServices obtenerServicioDeTokens() {
        DefaultTokenServices servicio = new DefaultTokenServices();
        servicio.setTokenStore(almacenDeTokens);
        return servicio;
    }
}

El método obtenerServicioDeTokens() define cómo se procesan los tokens recibidos. Existen dos escenarios principales:

  1. Servidor de recursos y servidor de autorización en la misma aplicación: Se configura DefaultTokenServices con un TokenStore local para la validación de tokens.
  2. Servicios separados (arquitectura de microservicios): Se utiliza RemoteTokenServices para validar tokens mediante una llamada al endpoint del servidor de autorización. Es necesario habilitar el endpoint de validación en el servidor de autorización:
@Override
public void configure(AuthorizationServerSecurityConfigurer seguridad) {
    seguridad
        .tokenKeyAccess("permitAll()")
        .checkTokenAccess("permitAll()")
        .allowFormAuthenticationForClients();
}

Adicionalmente, en una configuración separada, se debe establecer un control de seguridad a nivel de aplicación:

@Configuration
public class SeguridadWeb extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/perfil/**").authenticated()
            .anyRequest().permitAll();
    }
}

Prueba del servidor de recursos:

Crear un controlador simple:

@RestController
@RequestMapping("perfil")
public class ControladorPerfil {

    @GetMapping
    @PreAuthorize("hasAuthority('rol_administrador')")
    public Usuario obtenerPerfil() {
        Usuario usuario = new Usuario();
        usuario.setNombre("ejemplo_usuario");
        return usuario;
    }
}

Para probar, primero se obtiene un token (usando, por ejemplo, el flujo de contraseña) y luego se incluye en la solicitud al recurso protegido. Según la especificación OAuth 2.0:

  • El token debe enviarse en el encabezado HTTP.
  • El formato correcto es: Nombre del parámetro: Authorization, Valor: Bearer <token>.

Las solicitudes con tokens inválidos o sin token serán rechazadas por el servidor.

Etiquetas: Spring Security OAuth 2.0 Resource Server Token Validation Microservices Security

Publicado el 6-19 21:59