Spring Security系列教程24--Spring Security环境中存在的跨域问题

本文涉及的产品
.cn 域名,1个 12个月
简介: 前言在前后端不分离时,我们利用前面讲过的Spring Security的各种知识点,就可以实现对项目的权限管控。但是在前后端分离时,尤其是在引入了Spring Security后的前后端分离时,我们从前端发来的请求,就会存在一些问题。这些问题就是跨域而导致的问题!对于前后端分离时,跨域而产生的安全问题,我们该怎么解决呢?接下来请跟着 一一哥 来学习如何解决吧!在解决跨域问题之前,我们先来了解一下何为跨域问题,怎么产生的跨域问题,怎么解决这个跨域问题。一. 跨域问题的由来1. 同源策略跨域问题的产生,源自浏览器的一个同源策略。1.1 同源策略的概念同源策略是由 Netscap

前言

在前后端不分离时,我们利用前面讲过的Spring Security的各种知识点,就可以实现对项目的权限管控。但是在前后端分离时,尤其是在引入了Spring Security后的前后端分离时,我们从前端发来的请求,就会存在一些问题。这些问题就是跨域而导致的问题!

对于前后端分离时,跨域而产生的安全问题,我们该怎么解决呢?接下来请跟着 一一哥 来学习如何解决吧!

在解决跨域问题之前,我们先来了解一下何为跨域问题,怎么产生的跨域问题,怎么解决这个跨域问题。

一. 跨域问题的由来

1. 同源策略

跨域问题的产生,源自浏览器的一个同源策略。

1.1 同源策略的概念

同源策略是由 Netscape 提出的一个著名的安全策略,它是浏览器最核心也是最基本的安全功能,所有支持 JavaScript 的浏览器都会使用这个策略。在同源策略中,要求 域名、协议、端口 3部分都要相同

举例来说,http://www.yiyige.com:80/dir/syc.html这个网址,http是协议,www.yiyige.com是域名,80是端口号(80端口号默认可以省略)。同源策略具体规则如下表:

如果浏览器中没有对JavaScript进行同源限制,则有可能会利用浏览器的漏洞,出现以下针对服务器的攻击方式。

  • CSRF攻击
  • XSS攻击
  • 跨域问题

1.2 同源策略的作用

通过上一小节可知,同源策略的出现就是为了防止针对服务器的攻击,比如为了防止恶意网站通过冒充用户信息来窃取用户的敏感数据信息等,所以同源策略可以限制以下行为:

  • 限制读取Cookie、LocalStorage 和 IndexDB等信息;
  • 限制获取 DOM 和 JS 对象;
  • 限制发送Ajax请求。

即这个同源策略提高了攻击成本,保证了服务器的安全。

2. 跨域问题

2.1 跨域的作用

在上面的小节中,我给大家说到,浏览器出于安全方面的考虑,做了一个同源策略的限制,即不允许跨域访问其他资源,通俗的说就是浏览器中不能跨站执行其他网站的脚本,这是浏览器对JavaScript实施的一种安全限制。

2.2 跨域的概念

比如我们现在有一个地址http://store.company.com/dir/page.html,根据同源策略,如果对以下地址进行请求,产生的结果如下表所示:

也就是说如果域名、协议、端口号三者之间,只要有一个不同,就认为不是一个网站,也就可能会存在跨域问题。

二. 常见的攻击手段

在上面的小节中,我还给各位提到了几种攻击手段,接下来我们一起来了解一下这些攻击方式,了解其攻击原理,这样以后就可以想办法进行防御。

1. CSRF攻击

1.1 CSRF攻击

CSRF(Cross-Site Request Forgery)跨站请求伪造这是一种利用带有用户登录状态的cookie进行安全操作的攻击方式。攻击者会盗用你的身份,以你的名义来发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作。比如以你的名义发送邮件、发消息,盗取你的账号,添加系统管理员,甚至于购买商品、虚拟货币转账等。如下图所示: 其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户。

1.2 CSRF攻击原理及过程

  1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
  2. 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
  3. 用户未退出网站A之前,在同一浏览器中,打开另一个TAB页访问网站B;
  4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
  5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

1.3 CSRF防护措施

总体来说,CSRF攻击就是利用了系统对登录器用户的信任,使得用户执行了某些并非意愿的操作,从而造成用户的损失。所以我们对CSRF防护的一个重点是对“用户凭证”进行校验处理,通过这种机制可以对用户的请求是合法进行判断,判断是不是跨站攻击的行为。因为“用户凭证”是Cookie中存储的,所以防护机制的处理对像也是Cookie的数据,我们要在防护的数据中加入签名校验,并对数据进行生命周期时间管理,就是数据过期管理。

2. XSS攻击

2.1 XSS攻击

XSS又叫CSS(Cross Site Script),跨站脚本攻击。它是指恶意攻击者在Web页面里插入恶意的JavaScript代码,当用户浏览该网页时,嵌入在Web里面的JavaScript代码会被执行,从而达到恶意的特殊目的。XSS属于被动式的攻击,因为其被动且不好利用,所以许多人常呼略其危害性。

2.2 XSS攻击原理

2.3 XSS防护措施

防护XSS攻击其实就记住两条原则:过滤输入和转义输出。具体措施如下:

  • 在输入方面对所有用户提交内容进行可靠的输入验证,提交内容包括URL、查询关键字、http头、post数据等;
  • 在输出方面,在用户输内容中使用标签,标签内的内容不会解释,直接显示;
  • 严格执行字符输入字数控制;
  • 在脚本执行区中,应绝无用户输入。

三. 跨域问题的解决方案

1. 跨域解决方案

针对上文提到的跨域问题,我们肯定要想办法进行解决,现在常见的解决方案有很多种,比如:

  • Java后端进行跨域解决CORS;
  • 使用AJAX的JSONP;
  • 使用jQuery的JSONP插件;
  • document.domain + iframe 跨域解决方案;
  • window.name + iframe 跨域解决方案;
  • location.hash + iframe 跨域解决方案;
  • postMessage跨域解决方案;
  • WebSocket协议跨域解决方案;
  • node代理跨域解决方案;
  • nginx代理跨域解决方案;
  • ......

2. JSONP与CORS对比

在这些众多的解决方案中,最常用的是JSONP和CORS,其中比较传统的跨域解决方案是 JSONP。JSONP 虽然能解决跨域问题,但是有一个很大的局限性,那就是 只支持 GET 请求,而不支持其他类型的请求,在 RESTful 时代几乎就没什么用。

另外一种常见的解决方案是 CORS(跨域源资源共享,Cross-Origin Resource Sharing),它是一个 W3C 标准,或者说是一种针对浏览器的技术规范,提供了 Web 服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略,进而实现跨域访问。

3. CORS跨域解决方案

我这里主要是在SpringBoot项目中利用CORS技术,来解决跨域方案。

3.1 CORS简介

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)在CORS的规范中有一组新增的HTTP首部字段,允许服务器声明其提供的资源可以被哪些站点跨域使用。最终允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

CORS需要浏览器和服务器同时支持。它的通信过程,都是浏览器自动完成的,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX/Fetch通信没有差别,代码完全一样。浏览器一旦发现请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器,只要服务器实现了CORS接口,就可以跨源通信。

3.2 CORS请求分类

  • 简单请求(simple request): 简单请求就是表单请求,浏览器沿袭了传统的处理方式,不把行为复杂化,否则开发者可能转而使用表单,规避 CORS 的限制。
  • 非简单请求(not-so-simple request),也被称为“预检请求”。
  • 带凭证的请求,即携带了用户cookie等信息的请求。

接下来我对上面提到的简单请求和非简单请求进行详解,请继续往下看。

4. 简单请求

浏览器发出CORS简单请求,只需要 在头信息之中增加一个Origin字段

所谓的简单请求,就是指HEAD、GET、POST请求,并且HTTP的头信息是以下几种字段之一:
Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type。

注意:

Content-Type只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

简单请求原理图如下所示:

5. 非简单请求

简单请求之外的其余请求,就是非简单请求。浏览器发出CORS非简单请求,会在正式通信之前,增加了一次OPTIONS查询请求,称为"预检"请求(preflight),用于确认服务器是否允许跨域。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段,只有得到肯定的答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。非简单请求原理图如下:

6. 响应头详解

要实现CORS很简单,我们只需在服务端添加一些响应头,并且这样做对前端来说是无感知的,很方便,这些响应头如下:

  • Access-Control-Allow-Origin

该字段是必填字段。它的值要么是请求时Origin字段的具体值,要么是一个*,表示被允许的站点。

  • Access-Control-Allow-Methods

该字段是必填字段。它的值是逗号分隔的一个具体的字符串或者*,表示服务器允许跨域的请求方法。

注意:

返回的是所有支持的方法,而不单是浏览器请求的那个方法,这是为了避免多次"预检"请求。

  • Access-Control-Expose-Headers

该字段可选,仅在预检请求的响应字段中有效,表示服务器允许携带的请求头。当CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。

  • Access-Control-Allow-Credentials

该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,不发送Cookie,即false。如果对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json,这个值只能设为true。如果服务器不要浏览器发送Cookie,删除该字段即可。

  • Access-Control-Max-Age

该字段可选,用来指定本次预检请求的有效期,单位为秒。在有效期间,不用发出另一条预检请求。

注意:

如果在开发中,发现每次发起的请求都是两条,一次OPTIONS,一次正常请求。注意是每次,那么就需要配置Access-Control-Max-Age,避免每次都发出预检请求。

至此,我就给各位讲解了关于跨域问题的一些理论知识,接下来会在下一章节中,给大家讲解如何进行代码实现,敬请期待!

相关文章
|
2月前
|
Cloud Native Java 对象存储
面向未来的架构设计:Spring Cloud和Netflix OSS在云原生环境下的发展趋势
展望未来,随着5G、边缘计算等新技术的兴起,微服务架构的设计理念将会更加深入人心,Spring Cloud和Netflix OSS也将继续引领技术潮流,为企业带来更为高效、灵活且强大的解决方案。无论是对于初创公司还是大型企业而言,掌握这些前沿技术都将是在激烈市场竞争中脱颖而出的关键所在。
63 0
|
11天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
22 2
|
29天前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
68 2
|
2月前
|
XML JavaScript Java
Spring Retry 教程
Spring Retry 是 Spring 提供的用于处理方法重试的库,通过 AOP 提供声明式重试机制,不侵入业务逻辑代码。主要步骤包括:添加依赖、启用重试机制、设置重试策略(如异常类型、重试次数、延迟策略等),并可定义重试失败后的回调方法。适用于因瞬时故障导致的操作失败场景。
Spring Retry 教程
|
1月前
|
Cloud Native Java 对象存储
面向未来的架构设计:Spring Cloud和Netflix OSS在云原生环境下的发展趋势
面向未来的架构设计:Spring Cloud和Netflix OSS在云原生环境下的发展趋势
48 1
|
1月前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
详细介绍实现Java Spring Boot FCM推送教程
97 0
|
3月前
|
Java 数据库连接 Spring
一文讲明 Spring 的使用 【全网超详细教程】
这篇文章是一份全面的Spring框架使用教程,涵盖了从基础的项目搭建、IOC和AOP概念的介绍,到Spring的依赖注入、动态代理、事务处理等高级主题,并通过代码示例和配置文件展示了如何在实际项目中应用Spring框架的各种功能。
一文讲明 Spring 的使用 【全网超详细教程】
|
3月前
|
SQL Java 数据库连接
Spring Boot联手MyBatis,打造开发利器:从入门到精通,实战教程带你飞越编程高峰!
【8月更文挑战第29天】Spring Boot与MyBatis分别是Java快速开发和持久层框架的优秀代表。本文通过整合Spring Boot与MyBatis,展示了如何在项目中添加相关依赖、配置数据源及MyBatis,并通过实战示例介绍了实体类、Mapper接口及Controller的创建过程。通过本文,你将学会如何利用这两款工具提高开发效率,实现数据的增删查改等复杂操作,为实际项目开发提供有力支持。
193 0
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
169 2
下一篇
无影云桌面