Spring Boot CORSfilter – CORS预检频道没有成功
我需要在我的Spring Boot Web应用程序中添加CORSfilter。
我已经添加了CORS映射,如以下文档中所述http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html
这是我的配置:
@Configuration @EnableWebMvc public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { // @formatter:off registry .addMapping("/**") .allowedOrigins(CrossOrigin.DEFAULT_ORIGINS) .allowedHeaders(CrossOrigin.DEFAULT_ALLOWED_HEADERS) .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .maxAge(3600L); // @formatter:on } ... }
现在,当我尝试访问我的API时,我收到以下错误:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://example.com/api/v1.0/user. (Reason: CORS preflight channel did not succeed).
这是来自FF控制台的屏幕截图:
我做错了什么以及如何正确配置CORS标头以避免此问题?
我已经通过创建一个新的CORSfilter解决了这个问题:
@Component public class CorsFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token"); response.addHeader("Access-Control-Expose-Headers", "xsrf-token"); if ("OPTIONS".equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); } else { filterChain.doFilter(request, response); } } }
并将其添加到securty配置:
.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class)
更新 – 现在我切换到更现代化的方式:
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .cors() .and() ... } @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); configuration.setAllowedOrigins(Arrays.asList("*")); configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS")); configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token")); configuration.setExposedHeaders(Arrays.asList("x-auth-token")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", configuration); return source; } }
有同样的问题让CORS与spring数据rest一起使用,这就是我使用的filter代码。
/** * Until url{https://jira.spring.io/browse/DATAREST-573} is fixed * * @return */ @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); //config.setAllowCredentials(true); // you USUALLY want this config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("OPTIONS"); config.addAllowedMethod("HEAD"); config.addAllowedMethod("GET"); config.addAllowedMethod("PUT"); config.addAllowedMethod("POST"); config.addAllowedMethod("DELETE"); config.addAllowedMethod("PATCH"); source.registerCorsConfiguration("/**", config); return new CorsFilter(source); }
值得一提的是,以下组合解决方案对我有用:
1。
@Configuration public class CorsConfiguration { //This can be used in combination with @CrossOrigin on the controller & method. @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedMethods("HEAD","OPTIONS") .allowedHeaders("Origin", "X-Requested-With", "Content-Type", "Accept"); } }; } }
2. RestController类上的@CrossOrigin。 让@CrossOrigin
读取@RequestMapping
注释及其中的HTTP方法。 其余请求因CORS错误而被拒绝。
但是,如果您想在项目中使用spring security,那么您将对上述解决方案感到不满。
我使用的是春季启动版1.5.4.RELEASE。
正确处理飞行前OPTIONS请求是必要的,但对于跨站点资源请求的工作是不充分的。
在OPTIONS请求返回满意的标题后,对同一URL的任何后续请求的所有响应也必须具有必要的“Access-Control-Allow-Origin”标题,否则浏览器将吞下它们,它们甚至不会显示在调试器窗口中。 https://stackoverflow.com/a/11951532/5649869
目前推荐的做CORS的方法是
@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/api/**") .allowedOrigins("http://domain2.com") .allowedMethods("PUT", "DELETE") .allowedHeaders("header1", "header2", "header3") .exposedHeaders("header1", "header2") .allowCredentials(true).maxAge(3600); // Add more mappings... } }
这是基于https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-cors
但您还需要确保在WebSecurityConfig文件中启用了CORS并禁用了CSRF。
我曾经有一个问题,我的所有POST方法都不起作用(返回403 forbiden),而GET方法工作得很好,但这在CSRF被禁用后解决了