web-dev-qa-db-fra.com

Comment activer les en-têtes CORS dans Swagger/v2/api-docs proposé par Springfox Swagger?

J'ai le fichier suivant dans mon projet:

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

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

Et dans le Application.Java il y a:

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

Le JSON Swagger est disponible sous /v2/api-docs, cela fonctionne bien.

Ce que je voudrais faire, c’est d’activer les en-têtes CORS pour ce terminal.

Pour mes propres contrôleurs, j'ai ajouté @CrossOrigin aux classes de contrôleur, ces API ont alors des en-têtes CORS, cela fonctionne bien. Mais pour l'URL JSON Swagger, je n'ai pas écrit de contrôleur moi-même, je ne peux donc pas utiliser cette annotation.

J'ai ajouté la méthode suivante à la SwaggerConfig, comme décrit dans la section "Configuration globale CORS" dans Prise en charge CORS dans 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");
            }
        };
    }

Les deux instructions d'impression sont imprimées, la méthode est appelée. Mais quand j'appelle l'URL avec curl:

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

Les en-têtes CORS ne figurent pas dans la réponse. (Contrairement à mes propres méthodes de contrôleur, annotées avec @CrossOrigin, où la réponse contient les en-têtes CORS.)

J'utilise springfox-swagger2 version 2.7.0 et spring-boot-starter-web 1.5.2.

Que puis-je faire pour activer les en-têtes CORS sur le noeud final de l'API Swagger JSON?

5
Adrian Smith

Je pense que vous avez besoin d’un filtre Web générique, par opposition à la configuration Web Mvc.

@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

Merci à @Barath pour la réponse. La solution consistait à ignorer la documentation de Spring, ce code semble simplement ne pas fonctionner en silence.

(C'est dommage, les éléments Spring sont assez avancés quand ils fonctionnent. Par exemple, l'en-tête de réponse "Access-Control-Allow-Headers" de la demande de contrôle préalable est définie en fonction des en-têtes proposés par la méthode de l'API Java. )

Ignorez la mise en œuvre de CORS par Spring et faites la vôtre. J'ai mis le code ici qui a fonctionné pour moi:

@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() {}
}

N'oubliez pas d'ajouter tout @RequestHeader que vous avez utilisé dans une méthode REST à l'en-tête de réponse Access-Control-Allow-Headers

1
Adrian Smith