web-dev-qa-db-ja.com

Springfox Swaggerが提供するSwagger / v2 / api-docsでCORSヘッダーを有効にするにはどうすればよいですか?

プロジェクトに次のファイルがあります。

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

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

そして、Application.Javaには、

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

Swagger JSONは/v2/api-docsの下で使用でき、正常に動作します。

私がやりたいのは、そのエンドポイントのCORSヘッダーを有効にすることです。

自分のコントローラーの場合、コントローラークラスに@CrossOriginを追加しました。これらのAPIにはCORSヘッダーがあり、正常に機能します。しかし、Swagger JSON URLの場合、私は自分でコントローラーを作成していないため、そのアノテーションを使用できません。

Spring FrameworkのCORSサポート の「グローバルCORS構成」で説明されているように、SwaggerConfigに次のメソッドを追加しました。

    @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");
            }
        };
    }

両方の印刷ステートメントが印刷されるため、メソッドが呼び出されています。しかし、curlでURLを呼び出すと:

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

CORSヘッダーは応答に含まれていません。 (@CrossOriginで注釈が付けられた、私の独自のコントローラーメソッドとは対照的に、応答にはCORSヘッダーがあります。)

私は、springfox-swagger2バージョン2.7.0、およびspring-boot-starter-web 1.5.2を使用しています。

Swagger JSON APIエンドポイントでCORSヘッダーを有効にするにはどうすればよいですか?

11
Adrian Smith

Web Mvc構成ではなく、一般的なWebフィルターが必要だと思います。

@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);
}
7
Strelok

答えてくれて@Barathに感謝します。解決策はSpringのドキュメントを無視することでした、そのコードは静かに機能しないようです。

(残念なことに、Springは機能するときにかなり進んでいます。たとえば、プリフライトリクエストに対する "Access-Control-Allow-Headers"応答ヘッダーは、どのヘッダーに基づいて設定されているかJava APIメソッドは実際に提供します。)

SpringのCORSの実装は無視して、独自に実装してください。私のために働いたコードをここに入れました:

@Component
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
    throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Headers", "Foo, Bar, Baz");
        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {}

    @Override
    public void destroy() {}
}

@RequestHeader RESTメソッドで使用したAccess-Control-Allow-Headers応答ヘッダー

1
Adrian Smith