graphql-spring-boot icon indicating copy to clipboard operation
graphql-spring-boot copied to clipboard

Rest and graphql cors configuration conflict

Open jasonmontalto opened this issue 2 years ago • 2 comments

Bug Description I have a project that contains a both rest and graphql (via this kickstart). I have rest cors configured within a WebMvcConfigurer implementation that overrides the addCorsMapping and adds our custom cors needs. This works perfectly until I enable cors for graphql. Once cors is enabled, the custom mapping is completely ignored, causing all non graphql endpoints to no longer have cors enabled.

To Reproduce

  1. Scaffold a simple spring rest setup
  2. Configure cors mappings by Creating an @Configuration class that implements WebMvcConfigurer and overrides addCorsMappings to add cors mapping
  3. Add this graphql kickstart package
  4. View app and see cors working for rest eps configured above
  5. Enable cors through application.properties graphql.servlet.corsEnabled
  6. View app and see cors no longer working for rest eps configured above, but graphql ep is working with cors

Expected behavior I would assume (without any documentation suggesting otherwise) that both cors configurations should be honored.

Browser for test

  • Chrome/Edge but would assume this would be the case for any browser

Workaround Took a while to unravel what was going on, but was able to figure out a workaround by temporarily allowing overriding of beans and overriding the cors configuration bean that comes packaged with this library. This allowed me to add my custom cors implementation in addition to the graphql cors configuration. Overriding beans is not something I want to add to our codebase, but it showed a path forward.

So my solution was to not use the WebMvcConfigurer:addCorsMapping method and instead create my own custom bean that configures cors directly using CorsConfiguration. Something like below

Example of cors mapping setup:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/api/**")
      .allowedOriginPatterns("*")
      .allowedHeaders("*")
      .allowedMethods("*")
      .exposedHeaders("Authorization");
  }
}

Example of custom bean that was used as a workaround:

@Configuration
public class AppCorsConfiguration {

  @Bean
  public CorsFilter curionCorsConfiguration() {
    CorsConfiguration corsConfiguration = new CorsConfiguration();
    corsConfiguration.addAllowedOriginPattern("*");
    corsConfiguration.addAllowedHeader("*");
    corsConfiguration.addAllowedMethod("*");
    corsConfiguration.addExposedHeader("ExposedHeaderName");

    Map<String, CorsConfiguration> corsConfigurations = new LinkedHashMap<>(1);
    corsConfigurations.put("/api/**", corsConfiguration);

    UrlBasedCorsConfigurationSource configurationSource = new UrlBasedCorsConfigurationSource();
    configurationSource.setCorsConfigurations(corsConfigurations);
    configurationSource.setAllowInitLookupPath(true);

    return new CorsFilter(configurationSource);
  }
}

I am not sure if this actually a bug or expected behavior, but I found it very confusing. If it is expected behavior, would it be possible to add a note about cors configuration to the documentation?

Thanks, Jason

jasonmontalto avatar Jan 31 '22 18:01 jasonmontalto