Spring Boot CORS 过滤器 - CORS 预检通道未成功
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36809528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Boot CORS filter - CORS preflight channel did not succeed
提问by alexanoid
I need to add CORS filter to my Spring Boot web application.
我需要将 CORS 过滤器添加到我的 Spring Boot Web 应用程序中。
I have added CORS mappings as described in the following documentation http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html
我添加了 CORS 映射,如以下文档http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html 中所述
This is my config:
这是我的配置:
@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
}
...
}
Right now when I'm trying to access my API I receiving a following error:
现在,当我尝试访问我的 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).
This is a screenshot from FF console:
这是FF控制台的截图:
What am I doing wrong and how to properly configure CORS headers in order to avoid this issue ?
我做错了什么以及如何正确配置 CORS 标头以避免此问题?
回答by alexanoid
I have fixed this issue by creating a new CORS Filter:
我通过创建一个新的 CORS 过滤器解决了这个问题:
@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);
}
}
}
and added it to securty configuration:
并将其添加到安全配置中:
.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class)
UPDATED - More modern way nowadays which I switched to:
更新 - 现在我切换到更现代的方式:
@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;
}
}
回答by Romell
Had the same issue getting CORS to work with spring data rest, this was the filter code I used.
有同样的问题让 CORS 与 spring 数据休息一起工作,这是我使用的过滤器代码。
/**
* 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);
}
回答by Udith Indrakantha
This is very simple and working well. Within the class you wrote for Web Security Configurations, enter this line httpSecury.cors();
这非常简单并且运行良好。在您为 Web Security Configurations 编写的类中,输入此行httpSecury.cors();
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors(); // This enables cors
// Your codes
}
}
回答by Vijay Kalidindi
For what its worth, the following combination solution worked for me:
就其价值而言,以下组合解决方案对我有用:
1.
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. @CrossOrigin
on the RestController class. Having @CrossOrigin
reads the @RequestMapping
annotations and the HTTP methods in it. Rest of the requests are rejected with CORS error.
2.@CrossOrigin
关于 RestController 类。拥有@CrossOrigin
读@RequestMapping
注释和它的HTTP方法。其余请求因 CORS 错误而被拒绝。
But you will be out of luck with the above solution if you want to use spring security in your project.
但是,如果您想在项目中使用 spring 安全性,则上述解决方案将不走运。
I am using spring boot version 1.5.4.RELEASE.
我正在使用 Spring Boot 版本 1.5.4.RELEASE。
回答by Niranjan Panigrahi
if using spring-boot 2 below code is enough to solve cors issue and preflight issue
如果使用下面的代码 spring-boot 2 足以解决 cors 问题和预检问题
@Override
public void configure(WebSecurity web) throws Exception {
// web.ignoring().antMatchers(HttpMethod.OPTIONS, "/**");
web.ignoring().antMatchers("/resources/**", "/index.html", "/login.html", "/partials/**", "/template/**", "/",
"/error/**", "/h2-console", "*/h2-console/*");
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.applyPermitDefaultValues();
config.setAllowCredentials(true);// this line is important it sends only specified domain instead of *
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}
回答by hang gao
It's work for me
这对我有用
@Configuration
public class CorsConfig implements WebMvcConfigurer {
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS");
}
}
回答by Gabriel Gates
I still had the CORS error after following the two tutorials:
遵循两个教程后,我仍然遇到 CORS 错误:
First I followed the Web Security guide: https://spring.io/guides/gs/securing-web/#scratch
Second I followed the CORS guide: https://spring.io/guides/gs/rest-service-cors/#global-cors-configuration
首先,我遵循了网络安全指南:https: //spring.io/guides/gs/securing-web/#scratch
其次,我遵循了 CORS 指南:https: //spring.io/guides/gs/rest-service-cors/#global-cors-configuration
To resolve my issues after following these guides I had to add http.cors()
to the http security.
为了在遵循这些指南后解决我的问题,我必须添加http.cors()
到 http 安全性。
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
...
}
Adding the .cors()
allows it to use the @Bean
I declared for my CORS configuration.
添加.cors()
允许它使用@Bean
我为我的 CORS 配置声明的。
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:4200");
}
};
}
回答by meghana manjunath
Step 1: Add this annotation in your controller
第 1 步:在您的控制器中添加此注释
@CrossOrigin
public class JobController {}
Step2 : Add this in any of your Configuration
步骤 2:在您的任何配置中添加它
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
};
}
This will work only if you have @CrossOrigin annotation on your controller
仅当您的控制器上有 @CrossOrigin 注释时,这才有效
回答by Алексей Романов
Proper handling of the pre-flight OPTIONS request is necessary, but NOT SUFFICIENT for cross-site resource requests to work.
正确处理飞行前 OPTIONS 请求是必要的,但不足以使跨站点资源请求起作用。
After the OPTIONS request comes back with satisfactory headers, all responses to any subsequent requests to the same URL also have to have the necessary "Access-Control-Allow-Origin" header, otherwise the browser will swallow them, and they won't even show up in the debugger window. https://stackoverflow.com/a/11951532/5649869
在 OPTIONS 请求返回满意的标头后,对同一 URL 的任何后续请求的所有响应也必须具有必要的“Access-Control-Allow-Origin”标头,否则浏览器会吞下它们,它们甚至不会显示在调试器窗口中。 https://stackoverflow.com/a/11951532/5649869
回答by Kolawole
The current recommended way of doing CORS is
当前推荐的执行 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...
}
}
This is base on https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-cors
这是基于https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-cors
But you also need to make sure that CORS is enabled and CSRF is disabled in your WebSecurityConfig file.
但是您还需要确保在您的 WebSecurityConfig 文件中启用了 CORS 并禁用了 CSRF。
I once had an issue where all my POST methods are not working (returning 403 forbiden) while GET methods work just fine but this is solved after CSRF is disabled
我曾经遇到过一个问题,我的所有 POST 方法都不起作用(返回 403 forbiden)而 GET 方法工作得很好,但这在 CSRF 被禁用后解决了