千锋教育-做有情怀、有良心、有品质的职业教育机构

领取全套视频

关注千锋学习站小程序
随时随地免费学习课程

当前位置:首页  >  技术要点  >  正文
分享到:

爆破专栏丨Spring Security系列教程解决Spring Security环境中的跨域问题

时间:2021-12-20 14:29     来源: 作者:郭成刚

  上一章节中,一一哥 给各位讲解了同源策略和跨域问题,以及跨域问题的解决方案,在本篇文章中,我会带大家进行代码实现,看看在Spring Security环境中如何解决跨域问题。

  一. 启用Spring Security 的CORS支持

  1. 创建web接口

  我先在SpringBoot环境中,创建一个端口号为8080的web项目,注意这个web项目没有引入Spring Security的依赖包。然后在其中创建一个IndexController,定义两个测试接口以便被ajax进行跨域访问。8080项目的代码结构:

  @RestController

  public class IndexController {

  @GetMapping("/hello")

  public String hello() {

  return "get hello";

  }

  @PostMapping("/hello")

  public String hello2() {

  return "post hello";

  }

  }

  请参考如下代码结构进行项目创建。

图片1

  2. 执行ajax请求

  我们接下来再创建另一个端口号为8082的web项目,注意这个web项目也没有引入Spring Security的依赖包。接着在这里定义一个index.html页面,利用ajax跨域访问8080项目中的web接口。

  8082项目的代码结构:

<!DOCTYPE html>

<html lang="zh-CN">

<head>

    <meta charset="UTF-8">

    <title>Index</title>

    <script type="text/javascript" src="jquery-2.1.0.js"></script>

</head>

<body>

<div id="app"></div>

<input type="button" onclick="btnClick()" value="get请求">

<input type="button" onclick="btnClick2()" value="post请求">

 

<script>

    function btnClick() {

        $.get('http://localhost:8080/hello', function (msg) {

            $("#app").html(msg);

        });

    }

 

    function btnClick2() {

        $.post('http://localhost:8080/hello', function (msg) {

            $("#app").html(msg);

        });

    }

</script>

 

</body>

</html>  

  请参考如下代码结构进行项目创建。

图片2

  3. 发起跨域请求

  我们访问8082项目中的index.html页面,然后分别执行get与post请求,这时候就可以在浏览器的控制台上看到产生了CORS跨域问题,出现了CORS error状态,在请求头中出现了Referer Policy: strict-origin-when-cross-origin。

图片3

图片4

  4. 解决跨域问题

  既然现在产生了跨域问题,那么该怎么解决呢?其实我们可以采用如下两种方式之一来解决跨域问题。

  方式1:在接口方法上利用@CrossOrigin注解解决跨域问题

  @RestController

  public class IndexController {

  @CrossOrigin(value = "http://localhost:8082")

  @GetMapping("/hello")

  public String hello() {

  return "get hello";

  }

  @CrossOrigin(value = "http://localhost:8082")

  @PostMapping("/hello")

  public String hello2() {

  return "post hello";

  }

  }

  方式2:通过实现WebMvcConfigurer接口来解决跨域问题

  @Configuration

  public class WebMvcConfig implements WebMvcConfigurer {

  @Override

  public void addCorsMappings(CorsRegistry registry) {

  registry.addMapping("/**")

  .allowedOrigins("http://localhost:8082")

  .allowedMethods("*")

  .allowedHeaders("*");

  }

  }

  当进行了跨域设置之后,我们再次进行跨域请求,就可以看到请求成功了。

图片5

  二. Spring Security环境下的跨域问题解决

  1. 引入Spring Security依赖

  通过上面的配置,我们已经解决了Ajax的跨域请求问题,但是这个案例中也有潜在的威胁存在,常见的就是 CSRF(Cross-site request forgery) 跨站请求伪造。跨站请求伪造也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF,是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。

  所以为了提高网站的安全性,我在上面Spring Boot项目的基础之上,添加Spring Security的依赖包,但是暂时不进行任何别的操作。

  <dependencies>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-security</artifactId>

        </dependency>

    </dependencies>

  2. 重启8080项目进行测试

  接着我就重启8080这个Spring Boot项目,然后在8082项目中再次进行跨域请求,我们会发现在引入Spring Security后,再次产生了跨域问题。

图片6

  3. 解决Spring Security环境下跨域问题的3种方案

  通过实验可知,如果使用了 Spring Security,上面的跨域配置会失效,因为请求会被 Spring Security 拦截。那么在Spring Security环境中,如何解决跨域问题呢?这里我们有3种方式可以开启 Spring Security 对跨域的支持。

  3.1 方式一:开启cors方法

  我们在上面的案例之上,编写一个SecurityConfig配置类,在configure方法中,利用cors() 开启Spring Security 对 CORS 的支持:

  @EnableWebSecurity

  public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override

  protected void configure(HttpSecurity http) throws Exception {

  http.authorizeRequests()

  .anyRequest()

  .permitAll()

  .and()

  .formLogin()

  .permitAll()

  .and()

  .httpBasic()

  .and()

  //支持跨域访问

  .cors()

  .and()

  .csrf()

  .disable();

  }

  }

  3.2 方式二:进行全局配置

  第二种方式是去除上面的跨域配置,直接在 Spring Security 中做全局配置,如下:

  @EnableWebSecurity

  public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override

  protected void configure(HttpSecurity http) throws Exception {

  http.authorizeRequests()

  .anyRequest()

  .permitAll()

  .and()

  .formLogin()

  .permitAll()

  .and()

  .httpBasic()

  .and()

  //支持跨域访问

  .cors()

  .configurationSource(corsConfigurationSource())

  .and()

  .csrf()

  .disable();

  }

  @Bean

  public CorsConfigurationSource corsConfigurationSource() {

  UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

  CorsConfiguration configuration = new CorsConfiguration();

  configuration.setAllowCredentials(true);

  configuration.setAllowedOrigins(Collections.singletonList("*"));

  configuration.setAllowedMethods(Collections.singletonList("*"));

  configuration.setAllowedHeaders(Collections.singletonList("*"));

  configuration.setMaxAge(Duration.ofHours(1));

  source.registerCorsConfiguration("/**", configuration);

  return source;

  }

  }

  以上2个方法,都可以实现在Spring Security环境下的跨域访问。

  3.3 方式三:支持OAuth2的跨域访问

  我们开发时,还有一种情况就是支持 OAuth2 相关接口的跨域,比如用户要访问 OAuth2 中的 /oauth/token 等接口。我们可以配置一个全局的 CorsFilter 跨域过滤器类,核心代码如下:

  /**

  * 跨域配置方式3:定义全局跨域过滤器

  **/

  @Configuration

  public class GlobalCorsConfiguration {

  @Bean

  public CorsFilter corsFilter() {

  CorsConfiguration corsConfiguration = new CorsConfiguration();

  corsConfiguration.setAllowCredentials(true);

  corsConfiguration.addAllowedOrigin("*");

  corsConfiguration.addAllowedHeader("*");

  corsConfiguration.addAllowedMethod("*");

  UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();

  urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);

  return new CorsFilter(urlBasedCorsConfigurationSource);

  }

  }

  @EnableWebSecurity

  public class SecurityConfig extends WebSecurityConfigurerAdapter {

  @Override

  protected void configure(HttpSecurity http) throws Exception {

  //跨域方式3:

  http.requestMatchers()

  .antMatchers(HttpMethod.OPTIONS, "/oauth/**")

  .and()

  .csrf()

  .disable()

  .formLogin()

  .and()

  .cors();

  }

  }

  该方式也可以实现Spring Security中的跨域访问。

  4. 代码结构

  以下是本案例的代码结构,可以参考下图进行项目创建:

图片7

  至此,我就带各位解决了Spring Security环境中的跨域问题,你学会了吗?

图片8

关注WX公众号【Java架构栈】,跟着千锋一起学Java

  原创:千锋一一哥

  前言

相关文章

QQ技术交流群

千锋IT培训视频教程群
724707829

加入群聊

热门视频

开班信息

  • HTML5大前端班--------------------------------

    06.29抢座

  • HTML5大前端班--------------------------------

    06.08抢座

  • 云计算培训班--------------------------------

    06.19抢座

  • JavaEE培训班--------------------------------

    06.08抢座

  • 北京总部地址:北京市海淀区宝盛北里西区28号中关村智诚科创大厦4层
    北京沙河校区:北京市昌平区沙阳路18号北京科技职业技术学院广场服务楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 深圳校区地址:深圳市宝安区宝安大道5010号西部硅谷B座C区1层108
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 上海校区地址:上海市宝山区同济支路199号智慧七立方3号楼2-4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 广州校区地址:广州市白云区永平街永泰学山塘学山文化创意谷A1栋六楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 郑州二七区校区地址:郑州市二七区航海中路60号海为科技园C区10层
    郑州高新区校区地址:郑州市高新区金梭路与银杏路交叉口教育科技产业园南门D座4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 大连校区地址:辽宁省大连市高新园区爱贤街10号大连设计城A座901
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 武汉金融港校区地址:武汉市东新区光谷大道77号金融港B18栋三、四层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 成都校区地址:成都市高新区肖家河沿街138号肖家河大厦三楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 西安校区地址:西安市雁塔区高新六路52号立人科技C座西区4楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 杭州旺田校区:浙江省杭州市上城区九堡镇旺田书画城A座4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 青岛校区地址:青岛市市北区龙城路31号卓越世纪中心4号楼5层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 重庆校区地址:重庆市九龙坡区科园一路3号渝高大厦9楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 长沙校区地址:湖南省长沙市岳麓区麓谷企业广场A2栋三单元306号
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 哈尔滨校区地址:哈尔滨市松北区世泽路689号 科技创新城4号楼405
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 南京校区地址:南京市建邺区应天大街780号弘辉产业园1栋2层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 太原校区地址:太原市小店区长治路230号能源互联网大厦6层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 沈阳校区地址:辽宁省沈阳市浑南区世纪路16号东大软件园B园B1座A201
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 合肥校区地址:合肥市包河区徽州大道396号东方广场B座12A
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 贵阳校区地址:贵阳市云岩区延安东路37号物资大厦老楼9楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、网络营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 济南校区地址:济南市历下区历山路36号齐鲁师范学院利宝产业大厦3F
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python人工智能+数据分析培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、网络安全培训、区块链培训、影视剪辑包装培训、游戏原画培训、全媒体运营培训
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 千锋教育服务号

    了解千锋动态
    关注千锋教育服务号

  • 千锋教育移动站

    扫一扫快速进入
    千锋移动端页面

  • 千锋互联服务号

    扫码匿名提建议
    直达CEO信箱