1
votes

Problème de configuration de Spring Boot CORS - Méthode de demande de contrôle d'accès: POST

J'ai une configuration CORS:

2019-01-01 21:16:35.100 DEBUG 24848 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : OPTIONS "/auth/create-account", parameters={}
2019-01-01 21:16:35.104 DEBUG 24848 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.http.ResponseEntity<java.lang.Object> rest.AuthEndpoint.createAccount(NewAccountDTO)
2019-01-01 21:16:35.106 DEBUG 24848 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Opening JPA EntityManager in OpenEntityManagerInViewInterceptor
2019-01-01 21:16:35.112 DEBUG 24848 --- [nio-8080-exec-1] o.j.s.OpenEntityManagerInViewInterceptor : Closing JPA EntityManager in OpenEntityManagerInViewInterceptor
2019-01-01 21:16:35.112 DEBUG 24848 --- [nio-8080-exec-1] o.s.orm.jpa.EntityManagerFactoryUtils    : Closing JPA EntityManager
2019-01-01 21:16:35.112 DEBUG 24848 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed 403 FORBIDDEN

Cela fonctionne pour cette requête:

curl -v -XOPTIONS -H 'Access-Control-Request- En-têtes: content-type '-H' Origine: http: // localhost: 3001 'http: // localhost: 8080 / auth / create-account

Il renvoie 200

Cela ne fonctionne pas si j'ajoute Access-Control-Request-Method: POST

curl -v -XOPTIONS -H 'Access-Control-Request-Headers: content-type' -H 'Origine: http: // localhost: 3001' http: // localhost: 8080 / auth / create-account -H 'Access-Control-Request-Method: POST '

Voici le contrôleur:

@RestController
@RequestMapping("/auth")
public class AuthEndpoint {

@PostMapping("/login")
  public ResponseEntity<Object> doLogin(@RequestBody @Valid LoginDTO loginDTO) {
    LOGGER.debug("Attempting login {}", loginDTO);
    try {
    .....

Le journal de Spring dit:

  @Bean
  CorsConfigurationSource corsConfigurationSource() {
    LOGGER.info("Configuring CORS");
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000", "https://localhost:3000", "http://localhost:2199", "https://localhost:2199"));
    configuration.setAllowCredentials(true);
    configuration.setAllowedHeaders(
        Arrays.asList("Access-Control-Allow-Headers",
            "Access-Control-Allow-Origin", "Access-Control-Request-Method",
            "Access-Control-Request-Headers", "Origin", "Cache-Control",
            "Content-Type", "Authorization", "Accept"));
    configuration.setAllowedMethods(
        Arrays.asList("DELETE", "GET", "POST", "PATCH", "PUT"));
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
  }

On dirait que le servlet du répartiteur l'intercepte et le tue, mais seulement avec l'en-tête Access-Control-Request-Method , sans cet en-tête cela fonctionne.

Maintenant, si Je change de contrôleur pour ajouter ceci: @CrossOrigin (origins = "http: // localhost: 3000") les deux méthodes fonctionnent.

Ma question est de savoir comment configurer globalement mon tout un pp pour éviter d'avoir à décorer chaque contrôleur REST avec (qu'est-ce qui devrait être redondant) @CrossOrigin annotation?


2 commentaires

n'avez-vous pas regardé ceci - Configuration CORS globale ?


Ajoutez "OPTION" dans setAllowedMethod arrayList.


3 Réponses :


-1
votes

Ajoutez "Options" dans la méthode autorisée

  response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, PUT, PATCH, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me, Authorization, User-Accept-Language");
    if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
    } else {
            chain.doFilter(req, res);
    }


1 commentaires

J'essaye de faire ceci avec la configuration, pas un filtre personnalisé.



-1
votes

La configuration CORS globale de Spring MVC est décrite dans ce billet de blog que j'ai écrit et dans le Documentation de référence Spring Framework .

Spring Security détectera automatiquement la configuration Spring MVC CORS et l'exploitera pour autoriser les requêtes si vous activer le support CORS au niveau de Spring Security .


0 commentaires

0
votes

Le même problème nous a donné quelques maux de tête, mais nous avons réussi à trouver une solution avec Spring-Boot v2.3.3. Le problème ici est qu'une demande d'options avec un en-tête Origin et Access-control-request-method fonctionne bien tant que vous:

  1. Configurer CORS dans un WebMvcConfigurer .
  2. Définissez les OPTIONS dans les allowedMethods .
  3. N'ajoutez AUCUN autre CorsFilters.

Par exemple

@Bean
public CorsFilter corsFilterSwagger() {
    CorsConfiguration config = new CorsConfiguration();
    config.addAllowedOrigin("*");
    config.setMaxAge(1000L);

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/v2/api-docs", config);
    return new CorsFilter(source);
}

Cependant, nous avons également utilisé Swagger v2.9.2 et pour une raison étrange, le WebMvcConfigurer ci-dessus n'active pas CORS pour le Swagger / v2 / api-docs endpoint. La solution pour cela, trouvée dans cette réponse , est d'ajouter un bean CorsFilter par exemple

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods(HttpMethod.GET.name(), HttpMethod.HEAD.name(),
                                HttpMethod.OPTIONS.name(), HttpMethod.POST.name())
                .maxAge(1000L); // in seconds
    }
}

Le problème est que dès que nous avons ajouté cela, les demandes d'options ont recommencé à échouer. En fin de compte, nous avons mis à niveau Swagger vers la version 3.0.0 où le problème CORS pour le point de terminaison est résolu, donc après avoir supprimé CorsFilter, tout a bien fonctionné.


0 commentaires