Skip to main content
Advertisement

3.10 CORS Configuration

Browsers block API calls to a different origin (protocol + host + port) by default due to Same-Origin Policy. If the frontend is https://front.com and the API is https://api.com, the server must send CORS (Cross-Origin Resource Sharing) headers.

Reference: Spring Boot 3.2.x

1. What is CORS?

  • Origin: Protocol + host + port (e.g. https://front.com:443)
  • The browser may send a preflight (OPTIONS) request; the server responds with Access-Control-Allow-Origin and related headers to allow the actual request.

2. Global Config (WebMvcConfigurer)

@Configuration
public class WebConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("https://front.example.com", "http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
  • addMapping: URL pattern to apply CORS to
  • allowedOrigins: Allowed origins. * and allowCredentials(true) cannot be used together
  • allowedMethods: Allowed HTTP methods
  • allowedHeaders: Allowed request headers. * or enumerated list
  • allowCredentials: Allow cookies and authentication info
  • maxAge: Preflight response cache duration (seconds)

3. With Spring Security

When using Security, it is cleaner to configure CORS with a CorsConfigurationSource bean.

@Configuration
public class SecurityConfig {

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.authorizeHttpRequests(auth -> auth.anyRequest().authenticated());
return http.build();
}

@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("https://front.example.com"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE", "OPTIONS"));
config.setAllowedHeaders(List.of("*"));
config.setAllowCredentials(true);

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

4. Method/Controller Level (@CrossOrigin)

Use @CrossOrigin when you only want to allow specific APIs.

@RestController
@RequestMapping("/api/public")
@CrossOrigin(origins = "https://front.example.com", maxAge = 3600)
public class PublicController { ... }
  • When overlapping with global config, they are merged. In production, using global config uniformly is common.

tip

In production, restrict allowedOrigins to concrete domains and do not use * with allowCredentials(true) at the same time.

Advertisement