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?
3 Réponses :
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); }
J'essaye de faire ceci avec la configuration, pas un filtre personnalisé.
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 .
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:
WebMvcConfigurer
. OPTIONS
dans les allowedMethods
. 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é.
n'avez-vous pas regardé ceci - Configuration CORS globale ?
Ajoutez "OPTION" dans setAllowedMethod arrayList.