โ† Back to list

๐Ÿ›ก๏ธ Behind the Scenes of Spring Security: Mastering SecurityFilterChain Like a Pro

Spring Security has evolvedโ€Šโ€”โ€Šthe old WebSecurityConfigurerAdapter is gone, and the new SecurityFilterChain is now the backbone of Springโ€ฆ

Lakshika in Stackademic ยท 2025-10-13 17:18 ยท 0 claps ยท 3.4 min read
#security #code #behind #spring #spring-boot
Open on Medium โ†—

๐Ÿ›ก๏ธ โ€œBehind the Scenes of Spring Security: Mastering SecurityFilterChain Like a Proโ€

๐Ÿ›ก๏ธ โ€œBehind the Scenes of Spring Security: Mastering SecurityFilterChain Like a Proโ€

๐Ÿ›ก๏ธ Behind the Scenes of Spring Security: Mastering SecurityFilterChain Like a Pro

Spring Security has evolved โ€” the old WebSecurityConfigurerAdapter is gone, and the new SecurityFilterChain is now the backbone of Spring Boot security configuration.

If youโ€™ve ever wondered what happens behind the curtain when a request hits your secure API, or how filters decide whether to allow or deny access โ€” this guide is for you. ๐Ÿš€

Letโ€™s break down what SecurityFilterChain really is, why it replaced the old approach, and how to configure it the right way.

๐Ÿ” What Is a SecurityFilterChain?

Think of it as a sequence of filters that inspect and process every incoming HTTP request before it reaches your controllers.

Each filter has one job:

  • Authenticate users ๐Ÿง‘โ€๐Ÿ’ป
  • Check permissions ๐Ÿ”
  • Handle CSRF tokens ๐Ÿงพ
  • Redirect or deny unauthorized access ๐Ÿšซ

Together, these filters form a chain โ€” the SecurityFilterChain.

In short:

๐Ÿ”— Every request goes through the chain, and each filter decides what happens next.

โš™๏ธ Why WebSecurityConfigurerAdapter Was Replaced

Before Spring Security 5.7, we used this pattern ๐Ÿ‘‡

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .formLogin();
    }
}

That worked fine โ€” but it was:

  • Hard to test (tight coupling)
  • Not modular
  • Verbally heavy

Now, the modern Spring Security style uses beans instead. ๐Ÿ’ก

๐Ÿงฉ The New Way โ€” Defining SecurityFilterChain as a Bean

Hereโ€™s the new (and preferred) approach ๐Ÿ‘‡

@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable()) // disable CSRF for simplicity
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/public/**").permitAll() // public APIs
                .requestMatchers("/admin/**").hasRole("ADMIN") // restricted APIs
                .anyRequest().authenticated() // everything else
            )
            .formLogin(Customizer.withDefaults()) // enable form login
            .httpBasic(Customizer.withDefaults()); // enable basic auth
        return http.build();
    }
}

โœ… Advantages:

  • Uses modern functional style
  • Supports multiple filter chains
  • Easier to maintain and test

๐Ÿง  How It Works Internally

When you start your Spring Boot app:

  1. Spring Security creates a filter chain proxy (FilterChainProxy).
  2. Each request is checked against a list of configured SecurityFilterChains.
  3. The first chain that matches handles the request.
  4. Filters execute in order (e.g., CORS โ†’ CSRF โ†’ Authentication โ†’ Authorization).

If no chain matches, the request is processed as unsecured (open endpoint).

๐Ÿ’ก You can have multiple SecurityFilterChain beans, each handling a different path.

๐Ÿ” Example: Multiple SecurityFilterChains

Letโ€™s say you want different rules for /api/** and /admin/**.

@Configuration
@EnableWebSecurity
public class MultiSecurityConfig {@Bean
    @Order(1)
    public SecurityFilterChain adminChain(HttpSecurity http) throws Exception {
        http
            .securityMatcher("/admin/**")
            .authorizeHttpRequests(auth -> auth
                .anyRequest().hasRole("ADMIN")
            )
            .formLogin(Customizer.withDefaults());
        return http.build();
    }
    @Bean
    @Order(2)
    public SecurityFilterChain apiChain(HttpSecurity http) throws Exception {
        http
            .securityMatcher("/api/**")
            .authorizeHttpRequests(auth -> auth
                .anyRequest().authenticated()
            )
            .httpBasic(Customizer.withDefaults());
        return http.build();
    }
}

โœ… Each SecurityFilterChain applies only to matching URLs. ๐Ÿง  Order matters โ€” Spring picks the first matching chain.

๐Ÿงพ Adding a Custom Filter

Want to add your own logic (e.g., logging or token validation)? You can easily inject a custom filter into the chain.

@Component
public class RequestLoggingFilter extends OncePerRequestFilter {
@Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain filterChain)
                                    throws ServletException, IOException {
        System.out.println("๐Ÿ” Incoming request: " + request.getRequestURI());
        filterChain.doFilter(request, response);
    }
}

Then, plug it into your chain:

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http
        .addFilterBefore(new RequestLoggingFilter(), UsernamePasswordAuthenticationFilter.class)
        .authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
        .httpBasic(Customizer.withDefaults());
    return http.build();
}

โœ… Your custom filter executes before authentication. Perfect for request logging, rate limiting, or custom headers.

๐Ÿงฉ Bonus Tip: Testing Your Security Config

You can write quick tests using Springโ€™s MockMvc to ensure your security behaves correctly.

@SpringBootTest
@AutoConfigureMockMvc
class SecurityTests {
@Autowired
    private MockMvc mockMvc;
    @Test
    void whenAccessPublic_thenOk() throws Exception {
        mockMvc.perform(get("/public/hello"))
                .andExpect(status().isOk());
    }
    @Test
    void whenAccessAdminWithoutAuth_thenUnauthorized() throws Exception {
        mockMvc.perform(get("/admin/panel"))
                .andExpect(status().isUnauthorized());
    }
}

โœ… Helps you confirm that your SecurityFilterChain behaves as expected.

๐Ÿ”ฎ The Future of Spring Security Config

Spring Securityโ€™s move to SecurityFilterChain is part of a functional, declarative trend:

  • Less boilerplate ๐Ÿงฑ
  • More composable configurations
  • Easier testing & multiple chain support

If youโ€™ve been using WebSecurityConfigurerAdapter, itโ€™s time to embrace the future โ€” cleaner, leaner, and more powerful.

๐Ÿ TL;DR โ€” Key Takeaways

๐Ÿ’ฌ Final Thought

Spring Security isnโ€™t just a firewall โ€” itโ€™s a framework built around filter orchestration. Once you understand SecurityFilterChain, you understand how every request in your app is secured.

โ€œSecurity isnโ€™t a plugin โ€” itโ€™s a mindset. ๐Ÿ”โ€

A message from our Founder

Hey, Sunil here. I wanted to take a moment to thank you for reading until the end and for being a part of this community.

Did you know that our team run these publications as a volunteer effort to over 3.5m monthly readers? We donโ€™t receive any funding, we do this to support the community. โค๏ธ

If you want to show some love, please take a moment to follow me on LinkedIn, TikTok, **Instagram. You can also subscribe to our [weekly newsletter](https://newsletter.plainenglish.io/)**.

And before you go, donโ€™t forget to clap and follow the writer๏ธ!


๋ฉ”ํƒ€๋ฐ์ดํ„ฐ
post_id
dab68f96fecc
slug
๏ธ-behind-the-scenes-of-spring-security-mastering-securityfilterchain-like-a-pro-dab68f96fecc
url
https://blog.stackademic.com/%EF%B8%8F-behind-the-scenes-of-spring-security-mastering-securityfilterchain-like-a-pro-dab68f96fecc
canonical_url
https://blog.stackademic.com/%EF%B8%8F-behind-the-scenes-of-spring-security-mastering-securityfilterchain-like-a-pro-dab68f96fecc
author_url
https://medium.com/@lakshitagangola123
status
ok
fetched_at
2026-07-16 21:00:47