How do you configure global CORS in Spring WebFlux via WebFluxConfigurer?
answer
- addCorsMappings(CorsRegistry)
- addMapping -> allowedOrigins/Methods/Headers/Credentials/maxAge
- credentials(true) + '*' origins = illegal -> use allowedOriginPatterns
- Preflight OPTIONS auto-answered
- Spring Security CORS takes precedence
basics
~10 sOverride addCorsMappings(CorsRegistry) in a WebFluxConfigurer bean. Use registry.addMapping(pathPattern) and chain allowedOrigins, allowedMethods, allowedHeaders, allowCredentials, and maxAge to define which cross-origin requests are permitted.
solid answer
~40 sImplement WebFluxConfigurer and override addCorsMappings(CorsRegistry registry). Each registry.addMapping("/api/**") returns a CorsRegistration you chain: allowedOrigins or allowedOriginPatterns, allowedMethods, allowedHeaders, exposedHeaders, allowCredentials(true), and maxAge for preflight caching. This installs global CORS handled early in the reactive stack (the WebFlux CORS processing runs before controller dispatch and answers OPTIONS preflight automatically). A key gotcha: you cannot combine allowCredentials(true) with the wildcard allowedOrigins("*") — the browser rejects it; use allowedOriginPatterns instead. Also note that if Spring Security is present, its own CORS handling takes precedence and you typically wire a CorsConfigurationSource into the SecurityWebFilterChain rather than relying only on addCorsMappings. Controller-level @CrossOrigin can override or add to the global rules per handler.
code
java · 17 linesimport org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.config.CorsRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;
@Configuration
public class CorsConfig implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOriginPatterns("https://*.example.com") // credential-safe wildcard
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.exposedHeaders("X-Total-Count")
.allowCredentials(true)
.maxAge(3600);
}
}go deeper
Know CORS is set with addCorsMappings + addMapping and the allowed* chain.
Know the credentials-vs-wildcard rule and that preflight is handled automatically.
Explain where CORS runs in the reactive stack and the Spring Security precedence issue.
Design a single source of truth for CORS across Security and WebFlux, and reason about origin-pattern echoing and credential exposure risk.
## The callback `WebFluxConfigurer.addCorsMappings(CorsRegistry registry)` defines **global** Cross-Origin Resource Sharing rules for the reactive stack. CORS is a browser security mechanism: when JavaScript on origin A calls an API on origin B, the browser sends an `Origin` header and (for non-simple requests) a preflight `OPTIONS` with `Access-Control-Request-*` headers. The server must answer with matching `Access-Control-Allow-*` headers or the browser blocks the response. ## Building rules ```java registry.addMapping("/api/**") // path pattern the rule applies to .allowedOrigins("https://app.example.com") // exact origins // .allowedOriginPatterns("https://*.example.com") // patterns (needed with credentials + wildcards) .allowedMethods("GET", "POST", "PUT") .allowedHeaders("*") .exposedHeaders("X-Total-Count") .allowCredentials(true) // permit cookies / Authorization .maxAge(3600); // cache preflight for 1h ``` Each `addMapping` returns a `CorsRegistration`. Defaults if you don't set them: all origins (`*`) as patterns, methods GET/HEAD/POST, all headers, credentials false, maxAge 1800s. ## Where it runs in the reactive stack WebFlux performs CORS checks inside the `HandlerMapping` layer before dispatching to your handler, and it short-circuits preflight `OPTIONS` requests with the appropriate headers — you do not write an OPTIONS handler yourself. ## Gotchas - **Credentials + wildcard is illegal.** `allowCredentials(true)` with `allowedOrigins("*")` throws at startup / is rejected by the browser, because the spec forbids a wildcard `Access-Control-Allow-Origin` when credentials are allowed. Use `allowedOriginPatterns("*")` (Spring then echoes the specific origin) if you need both. - **Spring Security precedence.** With `spring-security` on the reactive stack, security filters run before the handler mapping; unless CORS is configured in the `SecurityWebFilterChain` (usually via `http.cors(...)` backed by a `CorsConfigurationSource`), preflight requests can be blocked before `addCorsMappings` ever applies. In secured apps, prefer configuring CORS through Security (which can reuse a `CorsConfigurationSource` bean). - **Per-handler override.** `@CrossOrigin` on a controller/method adds or overrides rules for that handler; global + annotation configs are combined. - **allowedOrigins vs allowedOriginPatterns.** The former is an exact allow-list; the latter supports wildcard patterns and is credential-safe. ## When to use - Use `addCorsMappings` for app-wide CORS policy in a WebFlux app that is not (or not yet) secured by Spring Security, or in combination with Security's `http.cors()` referencing a shared source.
- Why does allowCredentials(true) fail with allowedOrigins("*")?The CORS spec forbids returning a wildcard Access-Control-Allow-Origin when credentials are permitted, since it would let any site read authenticated responses. Spring rejects the combination; use allowedOriginPatterns("*"), which echoes the specific request origin instead of a wildcard.
- If Spring Security is on the classpath, is addCorsMappings enough?Often not — Security's WebFilter chain runs before the handler mapping and can block preflights first. You should enable CORS in the SecurityWebFilterChain (http.cors) backed by a CorsConfigurationSource; you can share that source so policy is defined once.
saying these in an interview costs you the question
- Saying you must write an explicit OPTIONS handler for preflight (WebFlux answers it automatically)
- Combining allowCredentials(true) with allowedOrigins('*')
- Assuming addCorsMappings overrides Spring Security's CORS handling