Handling CORS in Spring Boot

 

🌐 Handling CORS in Spring Boot

In the world of modern web development, Cross-Origin Resource Sharing (CORS) is a critical security feature implemented by browsers to restrict cross-origin HTTP requests. While it's an important defense mechanism, it can often lead to frustrating issues when developing APIs consumed by frontend clients hosted on a different domain or port.

In this blog post, we will explore what CORS is, why it's important, and how to effectively handle it in Spring Boot applications.


❓ What is CORS?

CORS (Cross-Origin Resource Sharing) is a security feature implemented by web browsers to restrict web pages from making requests to a different domain than the one that served the original web page.

For example:

  • Your frontend is running on http://localhost:3000

  • Your backend API is hosted on http://localhost:8080

By default, browsers will block frontend code from making AJAX requests to the backend due to the same-origin policy.

🚫 Typical CORS Error:

Access to XMLHttpRequest at 'http://localhost:8080/api/data' from origin 'http://localhost:3000' has been blocked by CORS policy.

✅ Enabling CORS in Spring Boot

Spring Boot provides multiple ways to enable and configure CORS in your application. Let’s look at all the available options.


🔧 1. Using @CrossOrigin Annotation

Spring allows fine-grained CORS configuration using the @CrossOrigin annotation at the controller or method level.

📌 Example:

@RestController
@RequestMapping("/api")
public class DataController {

    @CrossOrigin(origins = "http://localhost:3000")
    @GetMapping("/data")
    public List<String> getData() {
        return Arrays.asList("Item1", "Item2", "Item3");
    }
}

🔄 Global CORS Mapping:

To allow all origins:

@CrossOrigin(origins = "*")

⚙️ 2. Global CORS Configuration with WebMvcConfigurer

For centralized control, implement WebMvcConfigurer and override the addCorsMappings() method.

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:3000")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*")
                .allowCredentials(true);
    }
}

🔐 Options:

  • allowedOrigins: Specifies allowed domain(s)

  • allowedMethods: Allowed HTTP methods

  • allowedHeaders: Allowed request headers

  • allowCredentials: Supports cookies/authorization headers


🚀 3. Handling Preflight Requests

Browsers send a preflight OPTIONS request to check if the actual request is safe. Spring Boot handles these automatically if CORS is correctly configured.

If not, you may see this error:

Response to preflight request doesn't pass access control check.

Spring handles OPTIONS automatically when CORS is configured properly, but you can also explicitly allow it:

.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")

🧰 4. CORS with Spring Security

If you're using Spring Security, you must explicitly allow CORS in the security configuration:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
            .authorizeHttpRequests()
            .anyRequest().authenticated();

        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(List.of("http://localhost:3000"));
        configuration.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
        configuration.setAllowedHeaders(List.of("*"));
        configuration.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

🧠 Best Practices

  • Avoid * in production; use specific origins

  • Always test CORS using browser developer tools (Network tab)

  • Keep frontend and backend origins in sync during local development

  • Ensure that preflight responses include all necessary headers

  • Use environment-specific configurations


🔍 Debugging Tips

  • Use browser DevTools Console & Network tabs

  • Look for missing Access-Control-Allow-Origin headers

  • Confirm preflight OPTIONS requests are allowed

  • Check if cookies/auth tokens are sent and handled properly


🌐 Real-World Scenarios

  • SPA frontends (React, Angular) calling Spring Boot APIs

  • Third-party applications consuming your REST APIs

  • Mobile apps making API calls

  • API Gateways that route requests across multiple services


✅ Conclusion

Handling CORS is essential for secure and functional cross-domain communications. Spring Boot makes it relatively straightforward to configure CORS using annotations, global configuration, or integration with Spring Security.

By properly configuring CORS, you ensure a seamless experience for frontend applications without compromising security or compliance.

Previous
Next Post »