CORS Configuration for Secure APIs in Spring Boot

In today’s web applications, security and access control are top priorities. One crucial aspect often overlooked is CORS (Cross-Origin Resource Sharing). Without proper configuration, your API could be exposed to unintended domains. In this post, we’ll walk through everything you need to know about CORS Configuration for Secure APIs using Spring Boot.

We’ll explore what CORS is, why it matters, and how to configure it effectively for secure REST APIs.

CORS Configuration for Secure APIs in Spring Boot

🚦 What is CORS?

CORS is a browser security feature that restricts HTTP requests from scripts running in the browser on a different origin (domain, protocol, or port) than the server.

For example, a frontend running on http://localhost:3000 trying to call a backend API at http://localhost:8080 will trigger a CORS preflight request. If not configured properly, the browser will block the call.

🧠 Why CORS Matters for Secure APIs

  • Prevent unauthorized domains from accessing your APIs.
  • Control which methods, headers, and origins are allowed.
  • Enable frontend-backend interaction across domains securely.

πŸ› οΈ Project Setup

Ensure your Spring Boot project has the following setup:

Dependencies (pom.xml):




    org.springframework.boot
    spring-boot-starter-web


    org.springframework.boot
    spring-boot-starter-security


🧩 CORS Configuration for Secure APIs (Global Setup)

Use the following configuration class to apply global CORS rules.

πŸ“ com.kscodes.springboot.security.config.WebSecurityConfig.java


package com.kscodes.springboot.security.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;

import java.util.Arrays;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .cors().and()
            .csrf().disable()
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public/**").permitAll()
                .anyRequest().authenticated()
            );

        return http.build();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();

        config.setAllowedOrigins(Arrays.asList("http://localhost:3000", "https://yourdomain.com"));
        config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
        config.setAllowedHeaders(Arrays.asList("Authorization", "Content-Type"));
        config.setAllowCredentials(true);

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

πŸ§ͺ Test Controller

πŸ“ com.kscodes.springboot.security.controller.ApiController.java


package com.kscodes.springboot.security.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ApiController {

    @GetMapping("/api/public/data")
    public String publicData() {
        return "This is public API data.";
    }

    @GetMapping("/api/secure/data")
    public String secureData() {
        return "This is secured API data.";
    }
}

🎯 Key Takeaways

  • Use CorsConfiguration to define which origins, methods, and headers are allowed.
  • Use CorsConfigurationSource and register it globally.
  • You can restrict secure APIs to only allow trusted domains.

πŸ” Fine-Grained CORS on Specific Controller

If you don’t want to use a global CORS config, you can use @CrossOrigin on controllers.


@CrossOrigin(origins = "https://trusted-client.com")
@GetMapping("/api/public/data")
public String publicData() {
    return "Access granted only from trusted-client.com";
}

Use this sparingly if you want per-controller CORS Configuration for Secure APIs.

πŸ”„ CORS and Preflight Explained

Before making a real request, browsers often send a preflight OPTIONS request to verify CORS permissions.

Make sure your backend:

  • Responds to OPTIONS
  • Does not block it via CSRF or security filters

πŸ“Œ Conclusion

Proper CORS Configuration for Secure APIs is essential for enabling cross-domain requests safely. Spring Boot offers flexible options to configure CORS both globally and per-controller.

By limiting CORS to trusted origins and enabling only required methods and headers, you can significantly improve the security posture of your APIs.

πŸ”— Further Reading