springspring-mvcspring-bootspringfox

How do I enable CORS headers in the Swagger /v2/api-docs offered by Springfox Swagger?


I have the following file in my project:

@Configuration
@Order(Ordered.LOWEST_PRECEDENCE)
public class SwaggerConfig {

    @Bean
    public Docket apiSwagger2Documentation() { .... }
}

And in the Application.java there is:

@SpringBootApplication
@ComponentScan(basePackages = { ... })
@EnableSwagger2
public class Application {
    ...
}

The Swagger JSON is available under /v2/api-docs, that works fine.

What I would like to do, is to enable CORS headers for that endpoint.

For my own controllers, I have added @CrossOrigin to the controller classes, those APIs then have CORS headers, that works fine. But for the Swagger JSON URL I haven't written a controller myself, so I cannot use that annotation.

I have added the following method to the SwaggerConfig, as described in "Global CORS Configuration" in CORS support in Spring Framework.

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        System.out.println("*** corsConfigurer called");
        return new WebMvcConfigurerAdapter() {
            @Override public void addCorsMappings(CorsRegistry registry) {
                System.out.println("*** addCorsMappings called");
                registry.addMapping("/v2/api-docs");
            }
        };
    }

Both print statements get printed, so the method is being called. But when I call the URL with curl:

curl -H "Origin: foo.com"  \
   -H "Access-Control-Request-Method: GET"   \
   -X OPTIONS \ 
   --verbose  \
   http://localhost:9274/v2/api-docs

The CORS headers are not in the response. (In contrast to my own controller methods, annotated with @CrossOrigin, where the response does have the CORS headers.)

I am using springfox-swagger2 version 2.7.0, and spring-boot-starter-web 1.5.2.

What can I do to enable CORS headers on the Swagger JSON API endpoint?


Solution

  • I think you need a generic web filter as opposed to Web Mvc configuration.

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    
        // Allow anyone and anything access. Probably ok for Swagger spec
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
    
        source.registerCorsConfiguration("/v2/api-docs", config);
        return new CorsFilter(source);
    }