Skip to content

Add route-specific CORS configuration for MVC - #4172

Open
celikfatih wants to merge 1 commit into
spring-cloud:mainfrom
celikfatih:feature/3302-mvc-cors-support
Open

Add route-specific CORS configuration for MVC#4172
celikfatih wants to merge 1 commit into
spring-cloud:mainfrom
celikfatih:feature/3302-mvc-cors-support

Conversation

@celikfatih

Copy link
Copy Markdown

Resolves gh-3302

What this PR does / why we need it:
Currently, Spring Cloud Gateway MVC lacks the ability to define CORS configurations on a per-route basis via route metadata, a feature that exists in the WebFlux implementation. This PR introduces route-specific CORS configuration support for the MVC module.

How it was implemented:

  • Created GatewayCorsConfigurationSourceBuilder to extract CORS configurations from route metadata and construct an UrlBasedCorsConfigurationSource.
  • Maintained auto-configuration cleanliness by isolating the business logic within the builder.
  • Added a robust integration test suite (CorsPerRouteMvcTests) using HttpbinTestcontainers to verify actual and pre-flight requests, including edge cases like Double CORS mitigation (using RemoveResponseHeader), wildcard origins (allowedOriginPatterns), and custom headers.

Backward Compatibility:
The feature uses @ConditionalOnProperty(prefix = GatewayMvcProperties.PREFIX + ".cors", name = "enabled", matchIfMissing = true). It acts as a transparent "no-op" unless CORS metadata is explicitly defined on a route, ensuring zero disruption to existing applications while providing a global kill-switch if needed.

Checklist:

  • Code formatting applied (./mvnw spring-javaformat:apply)
  • Apache License headers added to new files
  • Javadoc included with @author tags
  • Commits are signed-off (DCO)

Resolves spring-cloudgh-3302

Signed-off-by: celikfatih <celikfatih@protonmail.com>
@celikfatih
celikfatih force-pushed the feature/3302-mvc-cors-support branch from 8b6d525 to 1cae098 Compare August 21, 2026 13:01
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = GatewayMvcProperties.PREFIX, name = "cors.enabled", matchIfMissing = true)
public CorsFilter corsFilter(GatewayMvcProperties properties) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we want to be mindful of the filter chain order. By default this will register as LOWEST_PRECEDENCE. If Spring Security is used it would reject any cors request before it even gets to the filter

public static CorsConfigurationSource build(GatewayMvcProperties properties) {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());

if (!CollectionUtils.isEmpty(properties.getRoutes())) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about routes not created via properties?

public static String extractPathPattern(RouteProperties route) {
if (!CollectionUtils.isEmpty(route.getPredicates())) {
for (PredicateProperties predicate : route.getPredicates()) {
if ("Path".equalsIgnoreCase(predicate.getName()) && !CollectionUtils.isEmpty(route.getPredicates())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

!CollectionUtils.isEmpty(route.getPredicates() isn't this checked above?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add CORS functionality to spring cloud gateway mvc

3 participants