Solve the CORS error with Spring Security

In my last article, I’ve solved the CORS error by implementing a method of the interface WebMvcConfigurer.

This interface has a method named addCorsMappings.

Here is the CORS configuration I’ve used:

@Configuration
public class WebConfig {

    @Bean
    public WebMvcConfigurer corsConfig() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("http://localhost:4200")
                        .allowedMethods(HttpMethod.GET.name(),
                                HttpMethod.POST.name(),
                                HttpMethod.DELETE.name())
                        .allowedHeaders(HttpHeaders.CONTENT_TYPE,
                                HttpHeaders.AUTHORIZATION);
            }
        };
    }
}

I’ve configured the routes, the frontend URL, the HTTP methods and the HTTP headers.

All seems good.

But this interface belongs to the dependency Web MVC.

All the requests handled by Web MVC will be impacted. The rest of the requests won’t be affected by this configuration. Requests like JSF, Servlet, JAX-WS, JAX-RS won’t be impacted by the CORS configuration.

And when using Spring Security, I want to protect absolutely all my routes.

Solve the CORS Error with Spring Security

When configuring Spring Security, I have a method like cors() in the HttpSecurity builder. But to use it, I need to implement a CorsConfigurationSource.

This class also comes from the Web MVC dependency. But when using Spring Security, this configuration is used in the CORS filter which impacts all the routes.

But if I only use Web MVC requests, both solutions will have the same behavior.

Let’s see now the solution integrated with Spring Security.

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
        configuration.setAllowedMethods(Arrays.asList("GET","POST"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .cors(c -> c.configurationSource(corsConfigurationSource()))
                .exceptionHandling(customizer -> customizer.authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED)))
                .csrf(AbstractHttpConfigurer::disable)
                .sessionManagement(customizer -> customizer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authorizeHttpRequests((requests) -> requests
                        .anyRequest().permitAll())
        ;
        return http.build();
    }
}

First, I define a bean where I configure the CorsConfigurationSource to map the CORS configuration on all the routes. That’s the same information as the configuration with WebMvcConfigurer.

But this bean is used in the Spring Security configuration. This way, Spring Security will inject the CORS configuration into the CORS filter.

Also, Spring recommends to configure the CORS with CorsConfigurationSource when using Spring Security.

For more details, check the following video.


Never Miss Another Tech Innovation

Concrete insights and actionable resources delivered straight to your inbox to boost your developer career.

My New ebook, Best Practices To Create A Backend With Spring Boot 3, is available now.

Best practices to create a backend with Spring Boot 3

Leave a comment

Discover more from The Dev World - Sergio Lema

Subscribe now to keep reading and get access to the full archive.

Continue reading