序言
OAuth2是一个关于授权的开放网络标准,允许用户授权第三方移动应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容。 OAuth2.0是OAuth协议的延续版本,但不向后兼容OAuth 1.0即完全废止了OAuth1.0。
代码请参考 https://github.com/AutismSuperman/springsecurity-example
应用场景主要有如下
- 第三方应用授权登录 在APP或者网页接入一些第三方应用时,时长会需要用户登录另一个合作平台,比如QQ,微博,微信的授权登录。
- 原生app授权 App登录请求后台接口,为了安全认证,所有请求都带token信息,如果登录验证、请求后台数据。
- 前后端分离单页面应用(spa) 前后端分离框架,前端请求后台数据,需要进行oauth2安全认证,比如使用vue、react后者h5开发的app。
OAuth2的一个流程
这幅图是OAuth2 官网的一幅图,讲述了OAuth2的 一个大体协议流程。
- (A)用户(资源所有者)打开 客户端 ,客户端 要求 用户 给予授权。
- (B)用户 同意给予 客户端 授权。
- (C)客户端 获得授权后,向 认证服务器 申请令牌。
- (D)认证服务器对 客户端 进行认证后,确认无误,同意发放令牌。
- (E)客户端 使用令牌,向 资源服务器 申请获取资源。
- (F)资源服务器 确认 令牌无误, 同意 向 客户端开放资源。
引用阮老师的话 OAuth2 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。
OAuth2四种不同的标准模式
OAuth2标准为了应对不同的场景,设计了四种不同的标准模式。分别是以下几种
- 授权码模式
- 简化模式
- 密码模式
- 客户端模式
先不提这接种原理到底是什么,先说明以下这几种模式的应用场景
- 授权码模式:第三方Web服务器端应用与第三方原生App
- 简化模式:第三方单页面应用
- 密码模式:自家单页应用与自家原生App
- 客户端模式:没有用户参与的,完全信任的服务器端服务
好知道这些后我们就来窥探以下这几种模式。
授权码模式 Authorization code
授权码模式是 四种模式中最繁琐也是最安全的一种模式,大概步骤如下
- (A) 用户访问客户端如果需要用户授权则将用户导向认证服务器
- (B) 如果用户在认证服务器上进行授权
- (C) 如果授权通过,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码
- (D) 客户端收到授权码后 拿着授权码向认证服务器索要 Access Token,这一步呢通常是在客户端后台完成
- (E) 认证服务器会和对客户端发来的授权码检测是否正确 返回 Access Token和 Refresh Token给客户端
这些步骤做完后,有了Access Token,既可以访问用户那些受保护的资源了。因为在这种模式中 Access Token不会经过浏览器或移动端的App,而是直接从服务端去交换,这样就最大限度的减小了 Access Token泄漏的风险。
简化模式Implicit
这种模式和 授权码模式有所不同,他省略了客户端去请求认证服务器的这一步
- (A) 用户访问客户端如果需要用户授权则将用户导向认证服务器
- (B) 用户在认证服务器上完成验证
- (C) 如果认证成功 认证服务器将Access Token以 Hash的形式存放在重定向 uri 的fargment中发送给浏览器
- (D) 浏览器访问重定向URI
- (E) 资源服务器返回一个脚本,用以解析uri Hash中的Access Token
- (F) 在浏览器里将Access Token解析出来
- (G) 将解析出的Access Token发送给client
这种模式呢有个弊端就是会把 Access Token暴漏出来,所以呢,该模式不支持refresh tokens,简化模式用于没有服务器端的第三方单页面应用,因为没有服务器端就无法使用授权码模式同样呢 该模式最容易受安全攻击。
用户名密码 Resource Owner Credentials
这种模式就比较简单了 密码模式是用户直接将自己的用户名密码交给客户端,客户端用用户的用户名密码直接换取Access Token。
- (A)用户将认证密码发送给client
- (B)客户端拿着用户的密码向认证服务器请求Access Token
- (C)认证服务器将Access Token和Refresh Token发送给客户端
这种模式十分简单,但是却意味着直接将用户敏感信息泄漏给了client,因此这就说明这种模式只能用于client是我们自己开发的情况下。
因此密码模式一般用于我们自己开发的原生App或者单页应用。
客户端凭证 Client Credentials
这是一种最简单的模式,只要client请求,我们就将Access Token发送给它。
- (A)客户端向认证服务器发送自己的身份信息,并请求Access Token
- (B)确认客户端信息无误后,将Access Token发送给客户端
这种模式是最方便但最不安全的模式, 就是因为这种太不安全,因此这种模式一般用来提供给我们完全信任的服务器端服务。在这个过程中不需要用户的参与。
总结
知道了这些概念后,在学习SpringSecurity 中的 Spring Social 和用来搭建自己的一套授权服务的 Spring OAuth2就会变的格外的简单。
本博文是基于springboot2.x 和security 5 如果有什么不对的请在下方留言。