OAuth 2.0 是授权领域的一个行业级标准协议,由 OAuth 发展而来,但不兼容前者。它所定义的授权流程,涵盖了 web、桌面、手机、电视等多种设备上的应用程序。
OAuth 2.0 授权类型概述
OAuth 2.0 是授权领域的一个行业级标准协议,由 OAuth 发展而来,但不兼容前者。它所定义的授权流程,涵盖了 web、桌面、手机、电视等多种设备上的应用程序。
概念
角色
- 资源所有者 (resource owner)
能够授予对受保护资源的访问权的实体,即资源的拥有者。例如,终端用户
- 资源服务器 (resource server)
寄宿受保护资源的服务器
- 客户端 (client)
经过资源所有者的授权,代其请求受保护资源的应用程序
- 授权服务器 (authorization server)
认证资源所有者并获得其授权后,向客户端签发访问令牌的服务器
令牌
- 访问令牌 (access token)
用于访问受保护资源的凭证
- 刷新令牌 (refresh token)
用于获取访问令牌的凭证
客户端类型
- 机密客户端 (confidential client)
能够为其凭证保密的客户端,例如,在后台服务器上运行的应用
- 公共客户端 (public client)
不能为其凭证保密的客户端,例如,在浏览器上运行的应用
需要注意,即使将凭证以二进制形式嵌入到移动应用程序中,这仍然被视作不保密
OAuth 2.0 协议流程
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
授权类型
资源所有者的密码凭证授权 (Resource Owner Password Credentials Grant)
+----------+
| Resource |
| Owner |
| |
+----------+
v
| Resource Owner
(A) Password Credentials
|
v
+---------+ +---------------+
| |>--(B)---- Resource Owner ------->| |
| | Password Credentials | Authorization |
| Client | | Server |
| |<--(C)---- Access Token ---------<| |
| | (w/ Optional Refresh Token) | |
+---------+ +---------------+
! 由于向 client 暴露了密码凭证,存在很大的安全风险,已不被推荐使用
隐式授权 (Implicit Grant)
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI --->| |
| User- | | Authorization |
| Agent -|----(B)-- User authenticates -->| Server |
| | | |
| |<---(C)--- Redirection URI ----<| |
| | with Access Token +---------------+
| | in Fragment
| | +---------------+
| |----(D)--- Redirection URI ---->| Web-Hosted |
| | without Fragment | Client |
| | | Resource |
| (F) |<---(E)------- Script ---------<| |
| | +---------------+
+-|--------+
| |
(A) (G) Access Token
| |
^ v
+---------+
| |
| Client |
| |
+---------+
隐式授权是为无服务器应用程序设计的,相比于验证码授权,它移除了交换验证码的步骤。但是,这种模式无法确认客户端收到了访问令牌,因此也不再被推荐使用
对于公共客户端(例如 native 应用和 javascript 应用),现在应当使用 PKCE 扩展的验证码授权流程
(A)客户端将用户导向认证服务器
(B)用户决定是否给于客户端授权
(C)假设用户给予授权,认证服务器将用户导向客户端指定的"重定向URI",并在URI的Hash部分包含了访问令牌
(D)浏览器向 Web 托管的客户端资源发出请求,其中不包括上一步收到的Hash值
(E)Web 托管的客户端资源返回一个网页,其中包含的脚本代码可以获取Hash值中的令牌
(F)浏览器执行上一步获得的脚本,提取出令牌
(G)浏览器将令牌发给客户端
客户端凭证授权 (Client Credentials Grant)
+---------+ +---------------+
| | | |
| |>--(A)- Client Authentication --->| Authorization |
| Client | | Server |
| |<--(B)---- Access Token ---------<| |
| | | |
+---------+ +---------------+
客户端凭证授权没有用户的参与,客户端本身就是资源所有者
授权码授权 (Authorization Code Grant)
+----------+
| Resource |
| Owner |
| |
+----------+
^
|
(B)
+----|-----+ Client Identifier +---------------+
| -+----(A)-- & Redirection URI ---->| |
| User- | | Authorization |
| Agent -+----(B)-- User authenticates --->| Server |
| | | |
| -+----(C)-- Authorization Code ---<| |
+-|----|---+ +---------------+
| | ^ v
(A) (C) | |
| | | |
^ v | |
+---------+ | |
| |>---(D)-- Authorization Code ---------' |
| Client | & Redirection URI |
| | |
| |<---(E)----- Access Token -------------------'
+---------+ (w/ Optional Refresh Token)
授权码授权是应用最广泛的一种授权模式,
(A)用户访问客户端,后者将前者导向认证服务器
(B)用户选择是否给予客户端授权
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码
(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)
! 对于机密客户端,步骤 D 发起的请求,还携带有客户端密钥(client secret)
刷新令牌授权 (Refresh Token Grant)
+--------+ +---------------+
| |--(A)------- Authorization Grant --------->| |
| | | |
| |<-(B)----------- Access Token -------------| |
| | & Refresh Token | |
| | | |
| | +----------+ | |
| |--(C)---- Access Token ---->| | | |
| | | | | |
| |<-(D)- Protected Resource --| Resource | | Authorization |
| Client | | Server | | Server |
| |--(E)---- Access Token ---->| | | |
| | | | | |
| |<-(F)- Invalid Token Error -| | | |
| | +----------+ | |
| | | |
| |--(G)----------- Refresh Token ----------->| |
| | | |
| |<-(H)----------- Access Token -------------| |
+--------+ & Optional Refresh Token +---------------+
出于安全性考虑,访问令牌仅在一段时间内有效
当旧的访问令牌过期时,客户端可以使用刷新令牌交换新的访问令牌,无需用户的参与
授权码交换验证密钥 (Proof Key for Code Exchange)
授权码劫持
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
| End Device (e.g., Smartphone) |
| |
| +-------------+ +----------+ | (6) Access Token +----------+
| |Legitimate | | Malicious|<--------------------| |
| |OAuth 2.0 App| | App |-------------------->| |
| +-------------+ +----------+ | (5) Authorization | |
| | ^ ^ | Grant | |
| | \ | | | |
| | \ (4) | | | |
| (1) | \ Authz| | | |
| Authz| \ Code | | | Authz |
| Request| \ | | | Server |
| | \ | | | |
| | \ | | | |
| v \ | | | |
| +----------------------------+ | | |
| | | | (3) Authz Code | |
| | Operating System/ |<--------------------| |
| | Browser |-------------------->| |
| | | | (2) Authz Request | |
| +----------------------------+ | +----------+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
过程 1 是一个安全的 API 调用,过程 2 和 3 受 TLS 保护,但是恶意程序可以在过程 4 截获授权码
PKCE 协议流程
+-------------------+
| Authz Server |
+--------+ | +---------------+ |
| |--(A)- Authorization Request ---->| | |
| | + t(code_verifier), t_m | | Authorization | |
| | | | Endpoint | |
| |<-(B)---- Authorization Code -----| | |
| | | +---------------+ |
| Client | | |
| | | +---------------+ |
| |--(C)-- Access Token Request ---->| | |
| | + code_verifier | | Token | |
| | | | Endpoint | |
| |<-(D)------ Access Token ---------| | |
+--------+ | +---------------+ |
+-------------------+
由于恶意程序没有 code_verifier ,所以即使拦截了授权码,也无法换取访问令牌
设备码授权 (Device Code Grant)
+----------+ +----------------+
| |>---(A)-- Client Identifier --->| |
| | | |
| |<---(B)-- Device Code, ---<| |
| | User Code, | |
| Device | & Verification URI | |
| Client | | |
| | [polling] | |
| |>---(E)-- Device Code --->| |
| | & Client Identifier | |
| | | Authorization |
| |<---(F)-- Access Token ---<| Server |
+----------+ (& Optional Refresh Token) | |
v | |
: | |
(C) User Code & Verification URI | |
: | |
v | |
+----------+ | |
| End User | | |
| at |<---(D)-- End user reviews --->| |
| Browser | authorization request | |
+----------+ +----------------+
设备码授权主要用于无浏览器或者输入受限的设备。例如,用户可以使用手机扫描二维码,协助完成电视应用的授权