Spring Boot: From Basics to Production · Securing APIs with Spring Security
CORS, CSRF and Security Headers
Configure browser-related protections correctly.
Configure CORS in Spring Security (http.cors(...) with a CorsConfigurationSource) so preflight requests are handled before authentication. Keep CSRF enabled for session/cookie-based apps (for SPAs, use CookieCsrfTokenRepository so JavaScript can send the token header). Spring Security adds sensible security headers by default (X-Content-Type-Options, frame options, cache control); add HSTS and a Content Security Policy for web apps.
@Bean
CorsConfigurationSource corsConfigurationSource() {
var config = new CorsConfiguration();
config.setAllowedOrigins(List.of("https://app.example.com"));
config.setAllowedMethods(List.of("GET", "POST", "PATCH", "DELETE"));
config.setAllowedHeaders(List.of("Authorization", "Content-Type", "X-XSRF-TOKEN"));
config.setAllowCredentials(true);
var source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/api/**", config);
return source;
}
// In the SecurityFilterChain of a cookie-based app:
// http.cors(Customizer.withDefaults())
// .csrf(csrf -> csrf.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()))
// .headers(h -> h.contentSecurityPolicy(csp -> csp.policyDirectives("default-src 'self'")));
Common pitfalls
- Wildcard origins with credentials.
- Configuring CORS only in MVC so Spring Security rejects preflights first.
- Disabling CSRF globally to 'fix' a 403.
Key points
- CORS via Spring Security
- CSRF on for cookie auth
- Default headers + HSTS + CSP
Further reading: Spring Security: CSRF
Practice questions
Why configure CORS in Spring Security rather than only in Spring MVC?
Answer
Preflight OPTIONS requests carry no credentials; if Security processes them first without CORS config, they're rejected before MVC's CORS handling runs.
A SPA using session cookies gets 403 on POST. What's the right fix?
Answer
Send the CSRF token: use CookieCsrfTokenRepository (readable XSRF-TOKEN cookie) and have the SPA send it in the X-XSRF-TOKEN header — not disabling CSRF.
Open in the app to mark lessons complete, take notes and track your progress.