-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Description
Description
Hi team,
I am encountering an issue in spring-cloud-gateway
related to how CORS configurations are handled during route refresh.
The GlobalCorsProperties
class stores the CORS configurations using a LinkedHashMap
to preserve insertion order:
@ConfigurationProperties("spring.cloud.gateway.globalcors")
public class GlobalCorsProperties {
private final Map<String, CorsConfiguration> corsConfigurations = new LinkedHashMap<>();
public Map<String, CorsConfiguration> getCorsConfigurations() {
return corsConfigurations;
}
}
However, in the CorsGatewayFilterApplicationListener
implementation, this insertion order is lost due to the following line:
var corsConfigurations = new HashMap<>(globalCorsProperties.getCorsConfigurations());
This results in the CORS rules being reordered, which affects route specificity resolution. For example, in the following YAML configuration:
corsConfigurations:
'[/api/v2/sensitive/**]':
allowedOriginPatterns: "*"
allowCredentials: true
allowedMethods:
- GET
- POST
allowedHeaders: '*'
exposedHeaders:
- X-Custom-Header
'[/api/**]':
allowedOriginPatterns:
- "https://example-docs.domain.com"
- "https://internal-tools.domain.net"
allowCredentials: true
allowedMethods:
- GET
- POST
allowedHeaders: '*'
We observe that the [/api/**]
rule is sometimes evaluated before the more specific [/api/v2/sensitive/**]
, resulting in CORS exceptions for requests that should match the specific rule.
Proposed Fix
To preserve the intended rule order and avoid these subtle and hard-to-debug issues, I propose changing:
var corsConfigurations = new HashMap<>(globalCorsProperties.getCorsConfigurations());
to:
var corsConfigurations = new LinkedHashMap<>(globalCorsProperties.getCorsConfigurations());
This change would ensure the ordering defined in configuration files is respected throughout the lifecycle of the application.
Contribution
If you agree with this change, I will send you a pull request with the update.
Let me know your thoughts.
Versions
The issue was observed using the following dependencies:
org.springframework.boot:spring-boot-gradle-plugin:3.4.5
org.springframework.boot:spring-boot-dependencies:3.4.5
org.springframework.cloud:spring-cloud-dependencies:2024.0.1
org.springframework.cloud.spring-cloud-gateway-server:4.2.1