return "post hello";
}
}
这个注解表示这两个接口接受来自 http://localhost:8081 地址的请求,配置完成后,重启 provider ,再次发送请求,浏览器控制台就不会报错了,consumer 也能拿到数据了。
此时观察浏览器请求网络控制台,可以看到响应头中多了如下信息:

这个表示服务端愿意接收来自 http://localhost:8081 的请求,拿到这个信息后,浏览器就不会再去限制本次请求的跨域了。
provider 上,每一个方法上都去加注解未免太麻烦了,有的小伙伴想到可以讲注解直接加在 Controller 上,不过每个 Controller 都要加还是麻烦,在 Spring Boot 中,还可以通过全局配置一次性解决这个问题,全局配置只需要在 SpringMVC 的配置类中重写 addCorsMappings 方法即可,如下:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:8081")
.allowedMethods("*")
.allowedHeaders("*");
}
}
/\*\* 表示本应用的所有方法都会去处理跨域请求,allowedMethods 表示允许通过的请求数,allowedHeaders 则表示允许的请求头。经过这样的配置之后,就不必在每个方法上单独配置跨域了。
**2.1 存在的问题**
了解了整个 CORS 的工作过程之后,我们通过 Ajax 发送跨域请求,虽然用户体验提高了,但是也有潜在的威胁存在,常见的就是 CSRF(Cross-site request forgery)跨站请求伪造。跨站请求伪造也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF,是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。
**3.SpringSecurity**
如果使用了 Spring Security,上面的跨域配置会失效,因为请求被 Spring Security 拦截了。
当引入了 Spring Security 的时候,我们有两种办法开启 Spring Security 对跨域的支持。
**3.1 方式一**
方式一就是在上一小节的基础上,添加 Spring Security 对于 CORS 的支持,只需要添加如下配置即可:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.and()
.httpBasic()
.and()
.cors()
.and()
.csrf()
.disable();
}
}
一个 .cors 就开启了 Spring Security 对 CORS 的支持。
**3.2 方式二**
方式二则是去除第二小节的跨域配置,直接在 Spring Security 中做全局配置,如下:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.and()
.httpBasic()
.and()
.cors()
.configurationSource(corsConfigurationSource())
.and()
.csrf()
.disable();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("*"));
configuration.setAllowedHeaders(Arrays.asList("*"));
configuration.setMaxAge(Duration.ofHours(1));
source.registerCorsConfiguration("/**",configuration);
return source;
}
}
通过 CorsConfigurationSource 实例对跨域信息作出详细配置,例如允许的请求来源、允许的请求方法、允许通过的请求头、探测请求的有效期、需要处理的路径等等。
使用这种方式就可以去掉第二小节的跨域配置了。
**4.OAuth2**
还有一种情况就是 OAuth2 允许跨域,如果用户要访问 OAuth2 端点,例如 /oauth/token ,出现了跨域该怎么配置呢?
主要是配置一个 CorsFilter,大家可以参考该篇文章,我这里就把核心配置类列出来:
@Configuration
public class GlobalCorsConfiguration {