Spring Security-35-跨域问题及解决方案

最近在使用过程中,遇到了这样一个问题,就是跨域的处理,算是踩的一个坑,记录一下

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接口的话,就会有跨域的问题,如下:
image

原因

问题出现的原因是浏览器在发送 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() 这个方法

配置完成之后,再次重启,然后访问,就会正常返回