Arquitectura de Spring Security y Filter Chain

Intermedio
Spring Boot
Spring Boot
Actualizado: 04/05/2026

Diagrama: tutorial-spring-security-arquitectura-filter-chain

Qué es la cadena de filtros de Spring Security

Spring Security se integra en el stack servlet como un único filtro, FilterChainProxy, que actúa como punto de entrada. Dentro de ese filtro, Spring Security ejecuta una cadena ordenada de filtros especializados, cada uno con una responsabilidad concreta: cargar el contexto de seguridad, autenticar, autorizar, proteger frente a CSRF o generar cabeceras seguras.

La abstracción que representa esa cadena es SecurityFilterChain. Desde Spring Security 6 y Spring Boot 3 la configuración se expresa declarando un bean de este tipo, en lugar de extender la antigua clase WebSecurityConfigurerAdapter.

Bean SecurityFilterChain

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
        return http
            .securityMatcher("/api/**")
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated())
            .csrf(AbstractHttpConfigurer::disable)
            .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .build();
    }
}

Cada bean SecurityFilterChain se aplica solo a las peticiones que coinciden con su securityMatcher. Puedes definir varias cadenas independientes para separar, por ejemplo, una API REST sin sesión y una aplicación MVC con formulario de login.

Orden de los filtros

Los filtros se ejecutan siempre en el mismo orden. Los más relevantes son:

  • DisableEncodeUrlFilter: desactiva la reescritura de URL con jsessionid.
  • SecurityContextHolderFilter: carga el SecurityContext asociado a la sesión.
  • HeaderWriterFilter: escribe cabeceras de seguridad en la respuesta.
  • CsrfFilter: valida el token CSRF en peticiones que lo requieren.
  • LogoutFilter, UsernamePasswordAuthenticationFilter, BearerTokenAuthenticationFilter, BasicAuthenticationFilter: se ocupan de la autenticación según el mecanismo elegido.
  • ExceptionTranslationFilter: traduce excepciones de seguridad en respuestas HTTP coherentes.
  • AuthorizationFilter: evalúa las reglas de acceso definidas en authorizeHttpRequests.

Filtros personalizados

Puedes insertar filtros propios antes o después de los filtros estándar usando http.addFilterBefore o http.addFilterAfter. Es el mecanismo clásico para integrar JWT, auditoría de accesos o controles de rate limiting.

http.addFilterBefore(new JwtAuthenticationFilter(authManager),
    UsernamePasswordAuthenticationFilter.class);

Entender este orden es clave para depurar errores de autenticación: un filtro que falla en mitad de la cadena impide que el controlador llegue a ejecutarse.

Múltiples SecurityFilterChain en la misma aplicación

Una aplicación corporativa típica expone al menos dos superficies HTTP con requisitos de seguridad distintos: una API REST stateless protegida con JWT para clientes SPA y móviles, y una zona web con formulario de login y sesión HTTP para usuarios internos. En Spring Security ambas conviven como SecurityFilterChain independientes, con un securityMatcher y una prioridad declarada mediante @Order.

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    @Order(1)
    SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
        return http
            .securityMatcher("/api/**")
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated())
            .csrf(AbstractHttpConfigurer::disable)
            .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults()))
            .build();
    }

    @Bean
    @Order(2)
    SecurityFilterChain webFilterChain(HttpSecurity http) throws Exception {
        return http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/", "/login", "/css/**").permitAll()
                .anyRequest().authenticated())
            .formLogin(form -> form.loginPage("/login"))
            .logout(Customizer.withDefaults())
            .build();
    }
}

La cadena con menor @Order se evalúa primero. Si el securityMatcher no encaja, Spring Security pasa a la siguiente cadena. Esta separación permite mantener CSRF activo en la zona web y desactivado en la API REST sin colisiones.

Debugging del orden de filtros

Para depurar el contenido real de cada cadena se activa el log de Spring Security en DEBUG o se expone el endpoint de Actuator mappings. Un fallo frecuente en proyectos corporativos es colocar un filtro JWT personalizado después del AuthorizationFilter: el usuario nunca llega autenticado al momento de evaluar las reglas y todas las peticiones devuelven 403. La solución es siempre insertarlo antes de UsernamePasswordAuthenticationFilter con addFilterBefore.

Casos de uso B2B

  • Banca y fintech: tres cadenas separadas para APIs públicas, back office y canal móvil, cada una con su propio filtro JWT, reglas de CORS y política de sesión.
  • Sector público: integración de filtro SAML 2.0 o Cl@ve como AuthenticationFilter propio antes del UsernamePasswordAuthenticationFilter.
  • Telco y ecommerce: un filtro de rate limiting (Bucket4j, Resilience4j) insertado al principio de la cadena para proteger endpoints de login y checkout frente a abuso.
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Spring Boot es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Spring Boot

Explora más contenido relacionado con Spring Boot y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

Comprender la arquitectura de Spring Security y el patrón de cadena de filtros. Identificar los filtros principales y su orden de ejecución. Configurar varias SecurityFilterChain coexistiendo en una misma aplicación.