6.2 Modern Security Configuration
← Back to Chapter 6: Spring Security & Authentication
In Spring Boot 3 and Spring Security 6, WebSecurityConfigurerAdapter is completely removed. Configuration is now entirely component-based, using functional Lambda DSL.
1. Component-Based SecurityFilterChain
Modern security configuration defines a @Bean returning SecurityFilterChain:
@Configuration
@EnableWebSecurity
@EnableMethodSecurity // Activates @PreAuthorize and @Secured
public class SecurityConfig {
private final JwtAuthenticationFilter jwtAuthFilter;
private final AuthenticationProvider authenticationProvider;
public SecurityConfig(JwtAuthenticationFilter jwtAuthFilter,
AuthenticationProvider authenticationProvider) {
this.jwtAuthFilter = jwtAuthFilter;
this.authenticationProvider = authenticationProvider;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
// 1. Disable CSRF for stateless REST APIs
.csrf(AbstractHttpConfigurer::disable)
// 2. Configure CORS
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
// 3. Stateless Session Management (No HttpSession)
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
// 4. Authorization Rules
.authorizeHttpRequests(auth -> auth
.requestMatchers(
"/api/v1/auth/**",
"/actuator/health",
"/swagger-ui/**",
"/v3/api-docs/**"
).permitAll()
.requestMatchers(HttpMethod.GET, "/api/v1/products/**").permitAll()
.requestMatchers("/api/v1/admin/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
// 5. Wire AuthenticationProvider and JWT Filter
.authenticationProvider(authenticationProvider)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
}
2. CORS (Cross-Origin Resource Sharing)
Frontends running on http://localhost:3000 calling backends on http://localhost:8080 are blocked by browser same-origin policy without CORS:
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("http://localhost:3000", "https://codewithsarvy.dev"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
config.setAllowedHeaders(List.of("Authorization", "Content-Type", "X-Correlation-Id"));
config.setAllowCredentials(true);
config.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
3. Why Disable CSRF in Stateless REST APIs?
Cross-Site Request Forgery (CSRF) relies on browsers automatically appending session cookies on cross-origin requests. Since stateless REST APIs authenticate via the Authorization: Bearer <token> header (which browsers never attach automatically), CSRF attacks are impossible, making CSRF tokens unnecessary overhead.