你能在 Spring 中完全禁用 CORS 支持吗?
Posted
技术标签:
【中文标题】你能在 Spring 中完全禁用 CORS 支持吗?【英文标题】:Can you completely disable CORS support in Spring? 【发布时间】:2017-11-25 15:26:51 【问题描述】:如CORS preflight request fails due to a standard header 中所述,如果您向OPTIONS
端点发送请求并设置了Origin
和Access-Control-Request-Method
标头,那么它们会被Spring 框架拦截,并且您的方法不会被执行。公认的解决方案是使用@CrossOrigin
注释来阻止Spring 返回403
。但是,我正在使用 Swagger Codegen 生成我的 API 代码,所以我只想禁用它并手动实现我的 OPTIONS
响应。
那么你可以在 Spring 中禁用 CORS 拦截吗?
【问题讨论】:
【参考方案1】:对于较新版本的 Spring Boot:
@Configuration
public class WebConfiguration implements WebMvcConfigurer
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**").allowedMethods("*");
Kotlin 方式
@Configuration
class WebConfiguration : WebMvcConfigurer
override fun addCorsMappings(registry: CorsRegistry)
registry.addMapping("/**").allowedMethods("*")
【讨论】:
【参考方案2】:来自他们的documentation:
如果你使用的是 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");
如果您使用的是 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 的回答也是正确的。但我不喜欢“自定义”过滤器。
如果你有 Spring Web Security 给你带来麻烦。检查this SO 答案。
【讨论】:
此配置为所有来源和所有端点启用 CORS,发送“Access-Control-Allow-Origin: *”,这与禁用它相反。 从 Spring 5.0 开始,WebMvcConfigurerAdapter 已被弃用,而改用 WebMvcConfigurer。【参考方案3】:尝试添加以下过滤器(您可以根据自己的需要和支持的方法自定义它):
@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);
【讨论】:
这篇文章被低估了!无论出于何种原因,我都无法让 CORS 在 spring-boot-starter-web 中工作......这篇文章解决了它! 这里也一样,花了几个小时解决了这个问题! 这里也一样,简洁明了。 同意。我正在使用所有 spring 文档,正是这一点使它对我有用。【参考方案4】:我在我的 Spring Boot 应用程序中使用 Spring Security,并允许从特定域(或所有域)进行访问。
我的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;
有时需要在测试前清除浏览器历史记录。
详细信息可以在这里看到: http://appsdeveloperblog.com/crossorigin-restful-web-service/
仅适用于使用 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)
);
...
旧版本。 在我的 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()
【讨论】:
http.cors().and().csrf().disable() 这个工作就像魅力......干杯 所有其他“现代”方法都失败了,但这种“旧版本”方法成功了!非常感谢! @lukas84 为你高兴 :) @KirillCh 老是金子。这是唯一对我有用的方法。谢谢!【参考方案5】:以前的答案几乎都是关于启用 CORS,这对我来说是禁用的。
@Configuration
public class MyConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http.cors().and().csrf().disable();
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurer()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**").allowedMethods("*");
;
【讨论】:
【参考方案6】:如果你至少有 Java 8,试试这个:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());
【讨论】:
【参考方案7】:Spring MVC
https://docs.spring.io/spring-framework/docs/5.3.13/reference/html/web.html#mvc-cors-global-java@Configuration(proxyBeanMethods = false)
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**").allowedMethods("*").allowedHeaders("*");
春季启动
https://docs.spring.io/spring-boot/docs/2.5.7/reference/htmlsingle/#features.developing-web-applications.spring-mvc.cors@Configuration(proxyBeanMethods = false)
public class MyConfiguration
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurer()
@Override
public void addCorsMappings(final CorsRegistry registry)
registry.addMapping("/**").allowedMethods("*").allowedHeaders("*");
;
Spring 安全性(使用 Spring MVC 或 Spring Boot)
https://docs.spring.io/spring-security/site/docs/5.5.3/reference/html5/#cors@Configuration(proxyBeanMethods = false)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(final HttpSecurity http) throws Exception
// ...
// see also: https://docs.spring.io/spring-security/site/docs/5.5.3/reference/html5/#csrf-when
http.csrf().disabled();
// if Spring MVC is on classpath and no CorsConfigurationSource is provided,
// Spring Security will use CORS configuration provided to Spring MVC
http.cors(Customizer.withDefaults());
【讨论】:
以上是关于你能在 Spring 中完全禁用 CORS 支持吗?的主要内容,如果未能解决你的问题,请参考以下文章