spring-cloud-gateway icon indicating copy to clipboard operation
spring-cloud-gateway copied to clipboard

Register CorsConfigurationSource in GatewayAutoConfiguration

Open msassak opened this issue 7 years ago • 8 comments

When using SCG with Spring Security, the CORS support provided by SCG is only a partial solution. Public routes permitted by the security config work as expected, but protected routes do not, as the security config executes before the CORS configuration, causing preflight CORS requests to those resources to be denied.

Enabling Spring Security's CORS support is easy. This solves the problem, but not before defining a CorsConfigurationSource bean from the content of GlobalCorsProperties. I was surprised to find that this was not done automatically by SCG when spring.cloud.gateway.globalcors.cors-configurations had already been defined. If this is the correct way to handle this (it appears to work as expected now), it would be a useful addition to SCG.

This is with Greenwich.M3, Spring Boot 2.1.0 and Spring Security 5.1.1.

For example, given the global CORS configuration from application.yml:

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            allowed-origins:
            - "https://foo.example.com"
            - "http://localhost:8080"
            allowed-methods:
            - "*"
            allowed-headers:
            - "*"
            allow-credentials: true

And the security configuration class:

@EnableWebFluxSecurity
@Configuration
public class SecurityConfig {

	@Bean
	public SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http)
			throws Exception {
		// @formatter:off
		http.cors().and()
			.authorizeExchange()
			.pathMatchers("/public/route/1", "/public/route/2").permitAll()
			.anyExchange().authenticated()
			.and().oauth2ResourceServer().jwt();
		// @formatter:on
		return http.build();
	}

	@Bean
	CorsConfigurationSource corsConfigurationSource(
			GlobalCorsProperties globalCorsProperties) {
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		globalCorsProperties.getCorsConfigurations()
				.forEach(source::registerCorsConfiguration);
		return source;
	}
}

Once .cors() is called on the ServerHttpSecurity object, the CorsConfigurationSource takes care of the rest.

If possible, it'd be great to see something like this in a future release of Spring Cloud Gateway. Thanks!

Links

  • https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.0.2.RELEASE/single/spring-cloud-gateway.html#_cors_configuration
  • https://docs.spring.io/spring-security/site/docs/5.1.2.RELEASE/reference/htmlsingle/#cors

msassak avatar Jan 08 '19 21:01 msassak

PR's are welcome. It would be great if the PR included a unit test that only passes with the additional functionality provided by the PR.

tony-clarke-amdocs avatar Jan 10 '19 01:01 tony-clarke-amdocs

Thanks. It'll take me a while to get to it, but I'll give it a shot when I have some time.

msassak avatar Jan 10 '19 15:01 msassak

I finally found this after hours banging my head on why OPTIONS requests were being blocked for my secured routes. Workaround works great and its nice that it reads from the global configuration to reduce code duplication

mlubavin-vg avatar Feb 02 '21 08:02 mlubavin-vg

@ryanjbaxter , is it still an option to add it to this project? We also were stuck on this issue for several hours because of the assumption that Spring Boot auto-configuration handles that for us... :wink: . The upside of this story: we got better insight into the config and CORS itself :laughing:

rob-valor avatar Apr 27 '23 13:04 rob-valor

We spent a fair amount of hours debugging this. At least documentation should be improved regarding CORS usage in Gateway as currently it doesn't do justice.

ViliusS avatar Nov 29 '23 19:11 ViliusS

My team just spent a good amount of time debugging this as well, completely believed auto-configuration handled this. There should be examples of working projects, had to derive the answer from vague SO posts displaying both CorsConfiguration bean and GlobalCorsProperties in yaml.

StevenPG avatar Dec 07 '23 21:12 StevenPG

I wasted my entire day to figure this one out. i think this should be added to auto-configuration 🥲

Sithira avatar Dec 12 '23 09:12 Sithira

+1

drunkcattt avatar Feb 04 '24 06:02 drunkcattt