OAuth 2.0 授权框架梳理

OAuth 2.0是一个委托访问授权框架。

即,若有三方应用想访问我在某网站的一些资源,我不必将用户名密码给它,而是采用OAuth 2.0授权流程,让资源网站通过我的授权给其下发一个访问令牌来实现该功能。

这样即省去了直接将密码交给三方网站的诸多风险,还可以很好的实现资源限制,令牌过期等细粒度控制。

OAuth 2.0框架应用广泛,如使用GitHub账号登录CSDN,这即是CSDN三方网站想借助GitHub账号能力,通过我的授权,使用我在GitHub的头像名称等基本信息,而实现一键登录。

OAuth 定义了4个角色。

  • Resource Owner(资源所有者) 对受保护资源进行访问授权的实体,若资源所有者是人,则指的是终端用户。

  • Resource Server(资源服务器) 对受保护资源提供服务,接收携带访问令牌的请求,并对其作出响应。

  • Client(客户端) 代表资源所有者及其授权发送请求,可以是跑在桌面,服务端或其它设备上的应用。

  • Authorization Server(授权服务器) 在对资源所有者鉴权成功后,并在取得资源所有者授权后,对客户端签发访问令牌。

授权服务器与资源服务器可能是一个服务,也可能是分开的两个服务。一个授权服务器可以给多个资源服务器签发令牌。

如图1,看一下OAuth 2.0大致的授权流程。

图1:OAuth 2.0大致授权流程(引自RFC6749

(A) 客户端请求资源所有者授权,授权请求虽可以直接发给资源所有者,但最好经过授权服务器中转。

(B) 客户端接收到了授权准许,授权准许类型取决于客户端的请求方式及授权服务器所支持的类型。

(C) 客户端携带授权准许请求授权服务器

(D) 授权服务器对客户端进行鉴权,包括对客户端的鉴权及对其所携带的资源所有者授权准许的校验,校验成功则发放访问令牌。

(E) 客户端携带访问令牌请求资源服务器上的受保护资源

(F) 资源服务器校验客户端携带的访问令牌,若令牌有效,则提供服务。

关于授权准许

授权准许为资源所有者同意客户端访问其受保护资源的证明,也是客户端用来获取访问令牌的基础。

OAuth 2.0定义了4种授权类型:授权码(authorization code),隐式授权(implicit),资源所有者密码证明(resource owner password credentials),客户端证明(client credentials),此外还支持扩展类型。

授权码

授权码的获取是通过将授权服务器作为客户端及资源所有者的中间层来实现的。

避免客户端直接向资源所有者获得授权。客户端通过浏览器等用户代理将资源所有者引导至授权服务器。

授权服务器对资源所有者进行鉴权并获得资源所有者对客户端要求访问的授权。

拿到授权码后,用户代理又将资源所有者引导回客户端。

因资源所有者仅被授权服务器鉴权,所以资源所有者的密钥从没有与客户端分享。

授权码模式还有一些优点,即提供了授权服务器对客户端进行鉴权的能力,而且访问令牌直接给了客户端,并没有经过资源所有者的用户代理。

隐式授权

隐式授权是授权码模式的简化版。用于客户端为诸如JS脚本语言实现的浏览器应用的优化模式。

隐式授权绕过了对客户端签发授权码,直接给客户端签发访问令牌。

在隐式授权模式中,签发访问令牌时,授权服务器未对客户端进行校验。某些情况下,客户端身份可以通过对回调路径(用于传递访问令牌)的校验进行识别。隐式授权中,访问令牌可能暴露给资源所有者及有权访问资源所有者用户代理的其它应用。隐式授权减少了请求次数,带来了便捷,但需要权衡其安全问题。

资源所有者密码证明

资源所有者密码证明(如用户名密码)可以直接用作授权准许以获取访问令牌。

该模式仅可在资源所有者充分信任客户端及其它授权类型不可用时使用。

客户端证明

客户端证明可以用在授权范围仅限于客户端控制的受保护资源,或者受保护资源之前已被授权服务器分配过。

客户端证明典型场景是用在客户端即是资源所有者的情况下,或者是获取对之前已被授权过的受保护资源的授权访问。

访问令牌

访问令牌是访问受保护资源的证明。访问令牌对客户端透明,用于标识访问范围,访问时段等。访问令牌可以是一个id,也可以是一个自包含验证信息的字符串。

更新令牌

更新令牌用于当访问令牌失效时获取新的访问令牌。不同于访问令牌的是,更新令牌只会发给授权服务器,不会与资源服务器交互。

下面参考图2,看一下更新令牌的使用。

图2:更新失效的访问令牌(引自RFC6749

(A) 客户端携带授权准许向授权服务器请求访问令牌。

(B) 授权服务器对客户端及授权准许进行校验,若校验通过,发放访问令牌及更新令牌。

(C) 客户端携带访问令牌对资源服务器进行受保护资源访问。

(D) 资源服务器校验访问令牌,若有效,则提供服务。

(E) 重复(C)及(D)两步直至访问令牌失效,若客户端已知访问令牌失效,则跳到步骤(G),否则进行另一次访问。

(F) 因访问令牌已失效,资源服务器返回访问令牌失效错误。

(G) 客户端携带更新令牌向授权服务器请求新的访问令牌。

(H) 授权服务器对客户端及更新令牌进行鉴权,若校验通过,则签发新的访问令牌及更新令牌。

参考资料

[1] https://en.wikipedia.org/wiki/OAuth

[2] https://oauth.net/2/

[3] https://tools.ietf.org/html/rfc6749