『Spring Security』OAuth2.0授权的相关基础知识

摘要:OAuth协议为用户资源的授权提供了一个安全的、开放而又简易的标准。

一简要介绍

(一)、授权概念

用户想要登录A网站A网站让用户提供第三方网站(即下文的B网站)的数据,证明自己的身份,这就是我们日常生活中常见的第三方登陆方式。其中获取第三方网站的身份数据,就需要OAuth(Open Authorization)授权。例如CSDN网站的登陆:
image-20200824083018105

OAuth的授权不会使第三方应用触及到用户的帐号信息(如用户名与密码),即第三方应用无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此OAuth是安全的。简单说,数据的所有者告诉B网站,同意授权A网站进入系统,获取用户数据。B网站从而产生一个短期的进入令牌(token),用来代替密码,供A网站使用。

令牌(token)与密码的作用是相同的,都可以借助其进入系统。但令牌和密码却也有一些差异:

  • 时间限制(令牌有时间限制,过期自动失效(一般过期前会自动刷新),用户无法干预;密码一般是长期有效的)
  • 权限范围(令牌一般只能读取用户数据(只读权限);密码一般是拥有完整的权限控制(读写权限))
  • 用户可控(用户可以撤销令牌,使其立即失效;密码一般是不允许被撤销的)

令牌和密码一样必须保密,泄露了令牌一般就等同于泄露了密码。

(二)、OAuth2.0相关概念

OAuth2.0的标准是 RFC 6749 文件。在其中可以发现,OAuth定义了四种角色:

  • 资源所有者(能够授予对受保护资源的访问权限的实体,一般指具体用户)
  • 资源服务器(托管受保护资源(一般是用户数据)的服务器,通常和授权服务器属于同一应用)
  • 客户端(提出受保护资源请求的应用程序,即第三方应用)
  • 授权服务器(发布令牌的服务器,即提供第三方登录服务的服务器)

img

图片来自网络

授权流程简单来说就是资源所有者(也就是用户)同意以后,授权服务器可以向客户端颁发令牌。客户端通过令牌,去请求资源服务器的数据。

授权流程的细节,详见后文。

(三)、OAuth2.0授权的四种方式

  • 授权码方式(最常用的方式,安全性也最高,适用于那些有后端的 Web 应用

    优点:授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。

  • 隐藏式/简化式(直接颁发令牌,没有上述颁发授权码这个步骤。适用于纯前端应用

    缺点:这种方式把令牌直接传给前端,是很不安全的。因此,只能用于一些安全要求不高的场景,并且令牌的有效期必须非常短,通常就是会话期间(session)有效,浏览器关掉,令牌就失效了。

  • 密码式(请求密码,并颁发令牌。适用于高度信任的应用

    缺点:这种方式需要用户给出自己的用户名/密码,显然风险很大,因此只适用于其他授权方式都无法采用的情况,而且必须是用户高度信任的应用。

  • 客户端凭证(适用于没有前端的命令行应用)

    缺点:这种方式给出的令牌,是针对第三方应用的,而不是针对用户的,即有可能多个用户共享同一个令牌。

无论哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)客户端**(client secret),这是为了防止令牌被滥用。没有备案过的第三方应用,是不会拿到令牌的。

二、授权码方式

(一)、OAuth2.0授权流程

下文的A、B网站与上文定义相同:用户想通过B网站的用户数据来使用A网站,必须通过A网站向B网站请求资源授权。

为了方便查阅,我将步骤都设为标题。图中的每一步都与下文步骤一一对应。

image-20200824102012133

1、A网站让用户跳转到B网站

  • A网站客户端申请授权的URI,包含以下参数:

    了解:URI是以一种抽象的,高层次概念定义统一资源标识,而URL则是具体的资源标识的方式。(具体区别请百度)

    • response_type(必选项):表示授权类型,此项值固定为"code"
    • client_id(必选项):表示客户端的ID
    • redirect_uri(可选项):表示重定向URI
    • scope(可选项):表示申请的权限范围
    • state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。

2、B网站要求用户登录,然后询问"A网站要求获得 xx 权限,你是否同意?"。如果用户同意,B网站就会重定向回A网站(或重定向URI),同时发回一个授权码

一般要得到用户授权,才会返回相关凭证,当然也可以设置为自动授权(不安全)。

  • B网站服务器回应A网站客户端的URI,包含以下参数:

    • code(必选项):表示授权码

    该码的有效期应该很短,通常设为10分钟,客户端只能使用该码一次,否则会被授权服务器拒绝。

    该码与客户端ID(client_id)和重定向URI(redirect_uri),是一一对应关系。

    • state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。

3、A网站使用授权码,向B网站请求令牌

  • A网站客户端B网站授权服务器申请令牌的HTTPS请求(请求必须时POST请求),包含以下参数:
    • grant_type(必选项):表示使用的授权模式,此项值固定为"authorization_code"。
    • code(必选项):表示上一步获得的授权码
    • redirect_uri(必选项):表示重定向URI,且必须与A步骤中的该参数值保持一致。
    • client_id(必选项):表示客户端IDJ

4、B网站验证授权码,如果通过,则返回令牌(Access Token)

  • B网站授权服务器发送的HTTPS回复(一段JSON数据),包含以下参数:
    • access_token(必选项):表示访问令牌
    • token_type(必选项):表示令牌类型,该值大小写不敏感,可以是bearer类型或mac类型(具体区别可以上网查阅)
    • expires_in(可选项):表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间
    • refresh_token(可选项):表示更新令牌,用来获取下一次的访问令牌
    • scope:表示权限范围,如果与客户端申请的范围一致,此项可省略

5、A网站使用令牌,向B网站请求用户数据

A网站客户端拿到验证凭证(Access Token)后,剩下的事情就很简单了。B网站资源服务器会提供一系列关于用户资源的API,A网站客户端持有验证凭证(Access Token)访问相应的API即可。

6、B网站验证令牌,如果通过,则返回用户数据

如果验证凭证(Access Token)是正确的,此时B网站资源服务器就会返回资源信息,此时整个OAuth流程就结束了。

全文完,请大家多多支持!!!

如有错误,希望你能指出来,互相交流

装载请指明出处