Spring Security — Filter Chain & JWT

Overview

Spring Security is a chain of servlet filters that runs before your controllers. In Spring Security 6 (Boot 3) you configure it via a SecurityFilterChain bean — the old WebSecurityConfigurerAdapter is removed.

Official: Spring Security Reference.

For a deeper dive on JWT internals and the request flow, see security/02 — Spring Security authentication.


Table of contents

  1. SecurityFilterChain bean
  2. Authorization rules
  3. OAuth2 resource server + JWT
  4. CSRF and REST APIs
  5. CORS
  6. Method security
  7. Interview questions
  8. Summary

1. SecurityFilterChain bean

@Bean
SecurityFilterChain security(HttpSecurity http) throws Exception {
    http
        .csrf(csrf -> csrf.disable())
        .sessionManagement(sm -> sm.sessionCreationPolicy(STATELESS))
        .authorizeHttpRequests(auth -> auth
            .requestMatchers("/actuator/health", "/public/**").permitAll()
            .requestMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated())
        .oauth2ResourceServer(o -> o.jwt(Customizer.withDefaults()));
    return http.build();
}

For multiple chains (e.g. one for /api/**, one for /web/**), order them with @Order — most specific first.


2. Authorization rules

  • requestMatchers("/path/**") — replaces older antMatchers/mvcMatchers.
  • authorizeHttpRequests — replaces older authorizeRequests (new lambda DSL).
  • Common matchers: permitAll, authenticated, hasRole("ADMIN"), hasAuthority("orders:write").

3. OAuth2 resource server + JWT

A resource server validates incoming JWTs using the issuer’s JWK set URI:

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          issuer-uri: https://idp.example.com/realms/app

That’s all you need — Spring fetches the public keys from /.well-known/openid-configuration and verifies signature + iss + exp on every request.

Authorization server issues tokens. Resource server validates them on every API call. Spring Boot can play either role.


4. CSRF and REST APIs

  • Cookie-based session app → keep CSRF protection enabled.
  • Stateless API with Authorization: Bearer ... → safe to disable CSRF.

Don’t disable CSRF blindly. The decision follows from whether browsers send credentials automatically (cookies do, headers don’t).


5. CORS

http.cors(Customizer.withDefaults());

Provide a CorsConfigurationSource bean, or use WebMvcConfigurer.addCorsMappings.

CORS is enforced by the browser, not your API. Disabling/loosening it doesn’t bypass authentication.


6. Method security

@EnableMethodSecurity
@Service
public class OrderService {

    @PreAuthorize("hasAuthority('orders:write')")
    public void ship(Long id) { ... }
}
  • @EnableMethodSecurity replaces the deprecated @EnableGlobalMethodSecurity.
  • @PreAuthorize runs before the method; @PostAuthorize runs after.
  • Works via AOP proxies — self-invocation skips the check (same trap as @Transactional).

7. Interview questions

Q: WebSecurityConfigurerAdapter replacement? A: Define a SecurityFilterChain bean with the HttpSecurity lambda DSL.

Q: How does JWT auth work in Spring Security? A: The resource server filter extracts the bearer token, validates signature + claims (iss, aud, exp) using the JWKS, then builds an Authentication in the SecurityContext.

Q: When do you disable CSRF? A: For stateless APIs that authenticate with the Authorization header (not cookies). Cookie-based sessions still need CSRF.

Q: 401 vs 403? A: 401 — not authenticated (token missing/invalid). 403 — authenticated but not permitted.

Q: @EnableGlobalMethodSecurity replacement? A: @EnableMethodSecurity (Spring Security 6).


8. Summary

Topic One line
Boot 3 config SecurityFilterChain bean
JWT oauth2ResourceServer.jwt() + issuer-uri
Sessions STATELESS policy for token APIs
Method security @EnableMethodSecurity + @PreAuthorize

Next steps


Happy Learning

Next: Testing — Slices & Testcontainers