OAuth2整理

1. 简介

OAuth 2.0是一个授权的标准,它允许第三方应用用户授权后,访问用户在某网站上存储的数据(如用户信息、照片、联系人列表)。

它有基本的模型,也有几种变种,下边分别来看看。

2. 基本模型

2.1 角色

  • Resource owner:资源拥有者,也就是用户
  • Client:第三方的应用,想要访问你在另一网站的数据
  • Resource Server:资源服务器,网站的业务服务
  • Authorization Server:鉴权中心,与资源服务属于一个厂商

2.2 流程

基本流程如下:

OAuth2基本模型流程

(1)用户打开客户端以后,客户端要求用户给予授权。

(2)用户同意给予客户端授权。

(3)客户端使用上一步获得的授权,向认证服务器申请令牌。

(4)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。

(5)客户端使用令牌,向资源服务器申请获取资源。

(6)资源服务器确认令牌无误,同意向客户端开放资源。

文章介绍,使用前,Application(Client)可以先向Authorization Server注册,包括ApplicationName、回调URL等。其实将回调URL直接当query传递给Authorization Server就能完成功能,但这样做便于Authorization Server去管理三方的应用。

2.3 变体

  1. Authorization Code:授权码模式,要求client有客户端、有服务器,使用最多的
  2. Implicit:隐含模式,client有客户端即可完成
  3. Resource Owner password:密码模式,账号密码都交代给第三方的模式,简单了解即可
  4. Client Credentials:客户端证书,第三方是自己方的情况,简单了解即可
  5. Device code,最晚出现的一种,对设备进行授权,简单了解即可

注:这些变体是对基本模型中的1-4步进行了变化,5-6步都是相同

3. Authorization Code:授权码模式

网上能找到的图一般是这个图:

AuthorizationCode原理图

它是从OAuth标准来的,这里为了详细阐述流程,用时序图来看:

Client拿到AccessToken之后,就可以访问ResourceServer的资源了。

这里有2个流程:

  1. client获取到Authorization Code,这个在标准里一般被称为"Authorization Code flow"
  2. client再次获取到AccessToken,这个在标准里被称为"Implicit flow"

这里不禁要问,有了authorization code之后,为什么还需要access token?

stackoverflow给出了回答,这里简单概括一下:

主要是因为安全原因,OAuth2.0 试图满足这两条标准:

  1. 希望允许开发人员使用非 HTTPS 重定向 URI,因为并非所有开发人员都拥有启用 SSL 的服务器;
  2. 不希望黑客能够通过拦截请求来窃取访问/刷新令牌;

在"Implicit flow"中,access token是以二进制帧的方式传输,而不是"Authorization Code flow"中以URL参数的方式,也就不容易被拦截与攻击了。

4. Implicit:隐式模式

这种模式access token立即返回,而不需要Authorization code。它不需要第三方应用服务器参与,直接在浏览器中完成。

整个流程如下:

OAuth2的Implicit模式

具体步骤如下:

(A)客户端将用户导向认证服务器。

(B)用户决定是否给于客户端授权。

(C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌。

(D)浏览器向资源服务器发出请求,其中不包括上一步收到的Hash值。

(E)资源服务器返回一个网页,其中包含的代码可以获取Hash值中的令牌。

(F)浏览器执行上一步获得的脚本,提取出令牌。

(G)浏览器将令牌发给客户端。

与Authorization Code相比,有2点差异:

  1. Authorization server返回的是经过Hash的Access Token,再经过脚本才能提取AccessToken
  2. D、E两步是在浏览器上完成,而不是在client

有人说是简化模式,从步骤上看,并没有觉得简化

5. Resource Owner password:密码模式

这种模式,用户将网站的账号、密码直接给了client,client拿着去申请accesss token。这种情况,需要用户对client很信任,如谷歌浏览器,存储了很多账号密码一般。

resourceOwnerPassword

(A)用户向客户端提供用户名和密码。

(B)客户端将用户名和密码发给认证服务器,向后者请求令牌。

(C)认证服务器确认无误后,向客户端提供访问令牌。

6. Client Credentials:客户端证书模式

这种没用户什么事啦,client直接申请Access Token。我觉得这种client与Authorization Server应该是一家的,不能称为第三方了。

clientCredentials

(A)客户端向认证服务器进行身份认证,并要求一个访问令牌。

(B)认证服务器确认无误后,向客户端提供访问令牌。

7. Device Code:设备码模式

这种模式比以上几种出现的晚,是在rfc8628(2019年)中出现,以上4种是在rfc6749(2012年)。国内的资料中很少提及,这里就简单说一下。

这种模式针对的是设备,它们没有浏览器,只有有限的输入能力,例如用户在电视(没有键盘)上登录视频流应用程序(优酷、腾讯视频等)。

流程如下:

DeviceCodeAuthorization

(A)设备向Authorization Server请求访问,并在请求中包含设备的标识符(Client Identifier)

(B)Authorization Server返回Device Code、User Code和一个验证URL

(C)设备将UserCode、验证URL给用户,并指示让他在浏览器上继续操作

(D)用户要在浏览器上访问验证URL,Authorization Server先对用户进行身份认证,然后提示用户输入user code,并想向用户询问,是否授权

(E)设备这时候通过Device Code、Client Identifier轮询Authorization Server是否完成授权

(F)Authorization Server给设备发放Access Token

8. 参考

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×