Search code examples
spring-bootmicroservicesspring-cloudnetflix-zuul

JS access to Spring REST services behind ZUUL blocked by CORS policy


I am putting together a small service-based platform using various Spring Cloud frameworks. The individual components are as follows:

  • an Eureka discovery server
  • a Spring-Config server
  • an Authentication server
  • a Zuul gateway server
  • a REST service
  • a PostgreSQL server
  • a simple JQuery-based client running in the browser

(yes this is based on the design presented in Manning's "Spring Microservices in Action")

This all works just fine in development. However I have recently deployed all this server-side stuff to an external server (running docker-compose) and I can no longer access the service endpoints.

When calling the service endpoints via JQuery I get the following error:

Access to XMLHttpRequest at 'https://my.domain.com/api/resource/123/subresource/456' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I have tried adding the following to the Zuul server (in the same @EnableZuulProxy Spring boot application class) :

@Bean
public FilterRegsitrationBean corsFilter() {

    UrlBaseCorsConfigurationSource source = 
        new UrlBasedCorsConfigurationSource();

    CorsConfiguration config = new CorsConfiguration();

    config.setAllowCredentials(true);

    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    config.addAllowedMethod("*");

    source.registerCorsConfiguration("*", config);

    FilterRegistrationBean<CorsFilter> bean = 
        new FilterRegistrationBean<>(new CorsFilter(source));

    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);

    return bean;
}

This yielded the same error.

Any ideas?


Solution

  • OK so I fixed it by removing all Cors configs from the services and added this to the Zuul gateway.

    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
    
            registry.addMapping("/**")
                    .allowedMethods("POST", "PUT", "GET", "OPTIONS", "DELETE", "HEAD");
        }
    }
    

    It works but I have no idea why my previous attempts don't (and I obviously hate fixing something without having understood how). So if anyone has any ideas...

    Cheers