Java 你能在 Spring 中完全禁用 CORS 支持吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44697883/
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
Can you completely disable CORS support in Spring?
提问by baynezy
As described in CORS preflight request fails due to a standard headerif you send requests to OPTIONS
endpoints with the Origin
and Access-Control-Request-Method
headers set then they get intercepted by the Spring framework, and your method does not get executed. The accepted solution is the use @CrossOrigin
annotations to stop Spring returning a 403
. However, I am generating my API code with Swagger Codegenand so I just want to disable this and implement my OPTIONS
responses manually.
如CORS 预检请求中所述,由于标准标头,如果您将请求发送到设置OPTIONS
了Origin
和Access-Control-Request-Method
标头的端点,那么它们会被 Spring 框架拦截,并且您的方法不会被执行。接受的解决方案是使用@CrossOrigin
注释来阻止 Spring 返回403
. 但是,我正在使用Swagger Codegen生成我的 API 代码,所以我只想禁用它并OPTIONS
手动实现我的响应。
So can you disable the CORS interception in Spring?
那么可以在Spring中禁用CORS拦截吗?
回答by Yuriy Yunikov
Try to add a following filter (you can customize it for you own needs and methods supported):
尝试添加以下过滤器(您可以根据自己的需要和支持的方法对其进行自定义):
@Component
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
final FilterChain filterChain) throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*");
response.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, HEAD");
response.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
response.addHeader("Access-Control-Expose-Headers", "Access-Control-Allow-Origin, Access-Control-Allow-Credentials");
response.addHeader("Access-Control-Allow-Credentials", "true");
response.addIntHeader("Access-Control-Max-Age", 10);
filterChain.doFilter(request, response);
}
}
回答by d0x
From their documentation:
从他们的文档:
If you are using Spring Web MVC
如果您使用的是 Spring Web MVC
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
}
}
If you are using Spring Boot:
如果您使用的是 Spring Boot:
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("HEAD", "GET", "PUT", "POST", "DELETE", "PATCH");
}
};
}
}
Yuriy Yunikov answer is correct as well. But I don't like the "custom" filter.
Yuriy Yunikov 的回答也是正确的。但我不喜欢“自定义”过滤器。
In case you have Spring Web Security which causes you trouble. Check thisSO Answer.
如果您有 Spring Web Security,这会给您带来麻烦。检查此SO 答案。
回答by Panthro
For newer versions of spring boot:
对于较新版本的 Spring Boot:
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*");
}
}
The Kotlin way
Kotlin 方式
@Configuration
class WebConfiguration : WebMvcConfigurer {
override fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/**").allowedMethods("*")
}
}
回答by Kirill Ch
I use Spring Security in my Spring Boot application and enable access from specific domains (or from all domains).
我在 Spring Boot 应用程序中使用 Spring Security 并启用从特定域(或所有域)的访问。
My WebSecurityConfig:
我的网络安全配置:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
// ...
@Override
protected void configure(HttpSecurity http) throws Exception {
// add http.cors()
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers("/get/**").permitAll()
.antMatchers("/update/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.httpBasic(); // Authenticate users with HTTP basic authentication
// REST is stateless
http.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
// To enable CORS
@Bean
public CorsConfigurationSource corsConfigurationSource() {
final CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(ImmutableList.of("https://www.yourdomain.com")); // www - obligatory
// configuration.setAllowedOrigins(ImmutableList.of("*")); //set access from all domains
configuration.setAllowedMethods(ImmutableList.of("GET", "POST", "PUT", "DELETE"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(ImmutableList.of("Authorization", "Cache-Control", "Content-Type"));
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Sometimes is needed to clear browser history before testing.
有时需要在测试前清除浏览器历史记录。
Detailed information may be seen here: http://appsdeveloperblog.com/crossorigin-restful-web-service/
详细信息可以在这里看到:http: //appsdeveloperblog.com/crossorigin-restful-web-service/
Just for those who use Angular. From Angular I run requests to backend:
仅适用于使用Angular 的人。我从 Angular 向后端运行请求:
export class HttpService {
username = '..';
password = '..';
host = environment.api;
uriUpdateTank = '/update/tank';
headers: HttpHeaders = new HttpHeaders({
'Content-Type': 'application/json',
Authorization: 'Basic ' + btoa(this.username + ':' + this.password)
});
constructor(private http: HttpClient) {
}
onInsertTank(tank: Tank) {
return this.http.put(this.host + this.uriUpdateTank, tank, {
headers: this.headers
})
.pipe(
catchError(this.handleError)
);
}
...
}
Old version.In my Spring Boot application no other ways worked then this:
旧版本。在我的 Spring Boot 应用程序中,没有其他方法可以工作:
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with, x-auth-token");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Credentials", "true");
if (!(request.getMethod().equalsIgnoreCase("OPTIONS"))) {
try {
chain.doFilter(req, res);
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
System.out.println("Pre-flight");
response.setHeader("Access-Control-Allowed-Methods", "POST, GET, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "authorization, content-type,x-auth-token, " +
"access-control-request-headers, access-control-request-method, accept, origin, authorization, x-requested-with");
response.setStatus(HttpServletResponse.SC_OK);
}
}
public void init(FilterConfig filterConfig) {
}
public void destroy() {
}
}