述
最近在使用过程中,遇到了这样一个问题,就是跨域的处理,算是踩的一个坑,记录一下
Spring boot 中跨域的处理
Spring boot中处理跨域的方式有很多种,这里不去一个一个细说,只写一个我用的解决方案,部分代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Autowired
private Constants constants;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins(constants.getCorsDomain()).maxAge(3600).allowedMethods("*");
}
};
}
这段代码,就随便写在一个配置类里面就可以了,然后这里有一个 constants.getCorsDomain()
,是一个数组,放的是允许跨域的域名
Spring Security遇到的问题
上面在 Spring boot 中的配置配置完成之后,是不是以为跨域问题就OK了, 其实并没有,这个时候是可以通过浏览器发get请求,而且也没有跨域的问题,但是去请求一个post接口的话,就会有跨域的问题,如下:
原因
问题出现的原因是浏览器在发送 POST 这种复杂请求的时候,会先发送一个 OPTIONS 的预检请求,来询问服务器是否支持跨域,支持的话,才会发送真实的 POST 登录请求, 但是 Spring Security ,会把所有的请求都拦截下来, 会认为这个 OPTIONS 请求也是需要登录才能访问的,所以这里会先返回一个401
解决方案
针对上面的问题,解决方案就是把所有的 OPTIONS 请求都放行,配置如下:1
.requestMatchers(CorsUtils::isPreFlightRequest).permitAll()
把这个加到权限的配置中去,然后再重启项目,再次访问,这时候 OPTIONS 请求可以正常发送返回了,而且真正的登录的 POST 请求也发送给服务器正常返回了,但是看不到返回值,原因还是跨域的问题,在Spring boot跨域的处理配置好的情况下,还需要给 Spring Security 做一些单独的配置
在资源服务器的配置中,如下:1
2
3
4
5
6
7
8
9
10
11@Override
public void configure(HttpSecurity http) throws Exception {
// 省略部分代码...
.and()
.cors()
// 省略部分代码...
;
authorizeConfigManager.config(http.authorizeRequests());
}
重点就是 .cors()
这个方法
配置完成之后,再次重启,然后访问,就会正常返回