在传统的客户端-服务器身份验证模型中,客户端通过使用资源所有者的凭据向服务器进行身份验证来请求服务器上的访问受限资源(受保护资源)。 为了向第三方应用程序提供对受限资源的访问,资源所有者与第三方共享其凭证。这产生了若干问题和限制。
-
第三方应用程序需要存储资源所有者的凭据以备将来使用,通常是明文密码。
-
要求服务器支持密码认证,尽管密码存在固有的安全弱点。
-
第三方应用程序获得对资源所有者受保护资源的过于广泛的访问权限,使资源所有者无法限制持续时间或访问有限的资源子集。
-
资源所有者不能在不撤销对所有第三方的访问权限的情况下撤销对单个第三方的访问权限,必须通过更改第三方的密码来实现。
-
任何第三方应用程序的泄露都会导致最终用户的密码和受该密码保护的所有数据泄露。
OAuth 通过引入授权层(authorization layer)并将客户端的角色与资源所有者的角色分开来解决这些问题。在 OAuth 中,客户端请求访问由资源所有者控制并由资源服务器托管的资源,并获得一组与资源所有者不同的凭据(credentials)。
客户端不是使用资源所有者的凭据来访问受保护的资源,而是获取访问令牌——一个表示特定范围(scope)、生命周期和其他访问属性的字符串。访问令牌由授权服务器(authorization server)在资源所有者的批准下颁发给第三方客户端。客户端使用访问令牌访问由资源服务器托管的受保护资源。
例如,最终用户(资源所有者)可以授予打印服务(客户端)访问其存储在照片共享服务(资源服务器)中的受保护照片的权限,而无需与打印服务共享其用户名和密码。相反,她直接向照片共享服务(授权服务器)信任的服务器进行身份验证,该服务器颁发打印服务委托特定的凭据(访问令牌)。
该规范设计用于 HTTP ([RFC2616])。
OAuth 1.0 协议 ([RFC5849]) 作为信息文档发布,是小型临时社区努力的结果。此标准跟踪规范建立在 OAuth 1.0 部署经验以及从更广泛的 IETF 社区收集的其他用例和可扩展性要求的基础上。
OAuth 2.0 协议不向后兼容 OAuth 1.0。这两个版本可以在网络上共存,并且实现可以选择同时支持这两个版本。但是,本规范的意图是新实现支持本文档中指定的 OAuth 2.0,并且 OAuth 1.0 仅用于支持现有部署。 OAuth 2.0 协议与 OAuth 1.0 协议共享很少的实现细节。熟悉 OAuth 1.0 的实施者应该接近本文档,不要对其结构和细节做任何假设。
Oauth 里的四个角色
资源所有者
能够授予对受保护资源的访问权限的实体。
当资源所有者是个人时,它被称为最终用户。
资源服务器
托管受保护资源的服务器,能够使用访问令牌接受和响应受保护资源请求。
# 客户 - client
代表资源所有者并经其授权发出受保护资源请求的应用程序。术语“客户端”并不意味着任何特定的实现特征(例如,应用程序是否在服务器、桌面或其他设备上执行)。
授权服务器(authorization server)
服务器在成功验证资源所有者并获得授权后向客户端颁发访问令牌。
授权服务器和资源服务器之间的交互超出了本规范的范围。
授权服务器可以是与资源服务器相同的服务器,也可以是单独的实体。
单个授权服务器可以发布多个资源服务器接受的访问令牌。
抽象的 OAuth 2.0 流程描述了四个角色之间的交互,包括以下步骤:
(A) 客户端向资源所有者请求授权。 授权请求可以直接发送给资源所有者,或者最好通过授权服务器作为中介间接发送。
(B) 客户端收到授权确认,这是代表资源所有者授权的凭证,使用本规范中定义的四种授权类型之一或使用扩展授权类型表示。授权授权类型取决于客户端请求授权的方法和授权服务器支持的类型。
(C) 客户端请求访问令牌,这是通过与授权服务器进行身份验证来完成。
(D) 授权服务器对客户端进行身份验证并验证授权许可,如果有效,则颁发访问令牌。
(E) 客户端向资源服务器请求受保护的资源,并通过提供访问令牌进行身份验证。
(F) 资源服务器验证访问令牌,如果有效,则为请求提供服务。
Authorization Grant
授权许可是一种凭证,表示客户端用于获取访问令牌的资源所有者授权(访问其受保护的资源)。 该规范定义了四种授权类型——授权代码、隐式、资源所有者密码凭据和客户端凭据——以及用于定义其他类型的可扩展性机制。
Authorization Code
授权码是通过授权服务器作为客户端和资源所有者之间的中介获得的。客户端不是直接从资源所有者请求授权,而是将资源所有者引导到授权服务器(通过其在 [RFC2616] 中定义的用户代理),后者又将资源所有者引导回带有授权代码的客户端。
在使用授权码将资源所有者引导回客户端之前,授权服务器对资源所有者进行身份验证并获得授权。由于资源所有者仅通过授权服务器进行身份验证,因此永远不会与客户端共享资源所有者的凭据。
授权代码提供了一些重要的安全优势,例如能够对客户端进行身份验证,以及将访问令牌直接传输到客户端,而无需通过资源所有者的用户代理并可能将其暴露给其他人,包括资源所有者。
Implicit
隐式授权是针对使用 JavaScript 等脚本语言在浏览器中实现的客户端进行了优化的简化授权代码流。在隐式流程中,不是向客户端发布授权代码,而是直接向客户端发布访问令牌(作为资源所有者授权的结果)。
授权类型是隐式的,因为没有颁发中间凭证(例如授权代码)(稍后用于获取访问令牌)。
在隐式授权流程期间发布访问令牌时,授权服务器不会对客户端进行身份验证。在某些情况下,可以通过用于将访问令牌传递给客户端的重定向 URI 来验证客户端身份。访问令牌可能会暴露给资源所有者或其他有权访问资源所有者的用户代理的应用程序。
隐式授权提高了某些客户端(例如作为浏览器内应用程序实现的客户端)的响应能力和效率,因为它减少了获取访问令牌所需的往返次数。然而,这种便利应该与使用隐式授权的安全隐患进行权衡,尤其是当授权代码授权类型可用时。
Resource Owner Password Credentials
资源所有者密码凭据(即用户名和密码)可以直接用作授权许可来获取访问令牌。 仅当资源所有者和客户端之间存在高度信任(例如,客户端是设备操作系统或高特权应用程序的一部分)并且其他授权授予类型不可用时,才应使用凭据( 例如授权码)。
尽管此授权类型需要客户端直接访问资源所有者凭据,但资源所有者凭据仍用于单个请求并交换访问令牌。 通过将凭据与长期访问令牌或刷新令牌交换,此授权类型可以消除客户端存储资源所有者凭据以备将来使用的需要。
Client Credentials
当授权范围仅限于客户端控制下的受保护资源,或先前与授权服务器安排的受保护资源时,客户端凭据(或其他形式的客户端身份验证)可用作授权许可。 客户端凭据通常用作授权授权,当客户端代表自己行事(客户端也是资源所有者)或根据先前与授权服务器安排的授权请求访问受保护资源时。
Access Token
访问令牌是用于访问受保护资源的凭据。访问令牌是一个字符串,表示颁发给客户端的授权。该字符串通常对客户端不透明。令牌代表特定的访问范围和持续时间,由资源所有者授予,并由资源服务器和授权强制执行
服务器。
令牌可以表示用于检索授权信息的标识符,或者可以以可验证的方式自包含授权信息(即,由一些数据和签名组成的令牌字符串)。为了让客户端使用令牌,可能需要额外的身份验证凭据,这超出了本规范的范围。
访问令牌提供了一个抽象层,用资源服务器理解的单个令牌替换了不同的授权结构(例如,用户名和密码)。这种抽象使得颁发访问令牌比用于获取它们的授权授予更严格,并且消除了资源服务器了解各种身份验证方法的需要。
根据资源服务器的安全要求,访问令牌可以具有不同的格式、结构和使用方法(例如,加密属性)。访问令牌属性和用于访问受保护资源的方法超出了本规范的范围,并由诸如 [RFC6750] 的配套规范定义。
Refresh Token
刷新令牌是用于获取访问令牌的凭据。 刷新令牌由授权服务器颁发给客户端,用于在当前访问令牌失效或过期时获取新的访问令牌,或者获取具有相同或更窄范围的附加访问令牌(访问令牌可能具有较短的生命周期和 比资源所有者授权的权限少)。
颁发刷新令牌是可选的,由授权服务器决定。 如果授权服务器发布刷新令牌,它会在发布访问令牌时包含在内。
刷新令牌是一个字符串,表示资源所有者授予客户端的授权。 该字符串通常对客户端不透明。 令牌表示用于检索授权信息的标识符。 与访问令牌不同,刷新令牌仅用于授权服务器,永远不会发送到资源服务器。
(A) 客户端通过与授权服务器进行身份验证并提供授权许可来请求访问令牌。
(B) 授权服务器对客户端进行身份验证并验证授权许可,如果有效,则颁发访问令牌和刷新令牌。
(C) 客户端通过提供访问令牌向资源服务器发出受保护的资源请求。
(D) 资源服务器验证访问令牌,如果有效,则为请求提供服务。
(E) 重复步骤 (C) 和 (D),直到访问令牌过期。如果客户端知道访问令牌已过期,则跳到步骤(G);否则,它会发出另一个受保护的资源请求。
(F) 由于访问令牌无效,资源服务器返回无效令牌错误。
(G) 客户端通过与授权服务器进行身份验证并提供刷新令牌来请求新的访问令牌。客户端身份验证要求基于客户端类型和授权服务器策略。
(H) 授权服务器对客户端进行身份验证并验证刷新令牌,如果有效,则颁发新的访问令牌(以及可选的新刷新令牌)。
Refreshing an Access Token
如果授权服务器向客户端发出刷新令牌,则客户端通过使用“application/x-www-form-urlencoded”格式添加以下参数向令牌端点发出刷新请求,其中字符编码为UTF-8 HTTP 请求实体主体:
-
授予类型:必需。值必须设置为“refresh_token”。
-
refresh_token:需要。发给客户端的刷新令牌。
由于刷新令牌通常是用于请求其他访问令牌的持久凭据,因此刷新令牌绑定到其颁发给的客户端。如果客户端类型是机密的,或者客户端获得了客户端凭据(或分配了其他身份验证要求),则客户端必须向授权服务器进行身份验证。
例如,客户端使用传输层安全性发出以下 HTTP 请求(额外的换行符仅用于显示目的):
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
授权服务器必须:
-
要求对机密客户端或任何已颁发客户端凭据(或具有其他身份验证要求)的客户端进行客户端身份验证
-
如果包含客户端身份验证,则对客户端进行身份验证,并确保将刷新令牌颁发给经过身份验证的客户端,以及
-
验证刷新令牌。
如果有效并获得授权,授权服务器会发出访问令牌。 如果请求验证失败或无效,授权服务器返回错误响应。
授权服务器可能会发出一个新的刷新令牌,在这种情况下,客户端必须丢弃旧的刷新令牌并用新的刷新令牌替换它。 授权服务器可以在向客户端发出新的刷新令牌后撤销旧的刷新令牌。 如果发布了新的刷新令牌,则刷新令牌的范围必须与客户端在请求中包含的刷新令牌的范围相同。
Security Considerations
Client Authentication
授权服务器与 Web 应用程序客户端建立客户端凭据以进行客户端身份验证。鼓励授权服务器考虑比客户端密码更强的客户端身份验证方法。 Web 应用程序客户端必须确保客户端密码和其他客户端凭据的机密性。
授权服务器不得出于客户端身份验证的目的向本机应用程序或基于用户代理的应用程序客户端发出客户端密码或其他客户端凭据。授权服务器可以为特定设备上本地应用程序客户端的特定安装发布客户端密码或其他凭据。
当客户端身份验证不可能时,授权服务器应该采用其他方式来验证客户端的身份——例如,通过要求注册客户端重定向 URI 或征集资源所有者来确认身份。在请求资源所有者授权时,有效的重定向 URI 不足以验证客户端的身份,但可用于防止在获得资源所有者授权后将凭据传递给伪造的客户端。
授权服务器必须考虑与未经身份验证的客户端交互的安全隐患,并采取措施限制向此类客户端颁发的其他凭据(例如刷新令牌)的潜在暴露。
Client Impersonation
如果被模拟的客户端未能或无法将其客户端凭据保密,则恶意客户端可以模拟另一个客户端并获得对受保护资源的访问权限。
授权服务器必须尽可能对客户端进行身份验证。如果由于客户端的性质授权服务器无法对客户端进行身份验证,则授权服务器必须要求注册任何用于接收授权响应的重定向 URI,并且应该使用其他方法来保护资源所有者免受此类潜在恶意客户端的侵害。例如,授权服务器可以让资源所有者协助识别客户端及其来源。
授权服务器应该强制执行明确的资源所有者身份验证并向资源所有者提供有关客户端和请求的授权范围和生命周期的信息。资源所有者可以在当前客户端的上下文中查看信息并授权或拒绝请求。
授权服务器不应该在没有验证客户端或依赖其他措施的情况下自动处理重复的授权请求(没有主动的资源所有者交互),以确保重复的请求来自原始客户端而不是模仿者。
Access Tokens
访问令牌凭证(以及任何机密的访问令牌属性)必须在传输和存储过程中保密,并且只能在授权服务器、访问令牌对其有效的资源服务器以及访问令牌颁发给的客户端之间共享.访问令牌凭证必须仅使用 TLS 传输,并使用 [RFC2818] 定义的服务器身份验证。
使用隐式授权类型时,访问令牌在 URI 片段中传输,这可能会将其暴露给未授权方。
授权服务器必须确保未授权方无法生成、修改或猜测访问令牌以生成有效的访问令牌。
客户端应该请求具有最小必要范围的访问令牌。授权服务器应该在选择如何接受请求的范围时考虑客户端身份,并且可以发布权限少于请求的访问令牌。
本规范没有为资源服务器提供任何方法来确保授权服务器向该客户端颁发给定客户端提供给它的访问令牌。
Refresh Tokens
授权服务器可以向 Web 应用程序客户端和本机应用程序客户端发出刷新令牌。
刷新令牌在传输和存储过程中必须保密,并且只能在授权服务器和刷新令牌发给的客户端之间共享。
授权服务器必须维护刷新令牌和它被颁发给的客户端之间的绑定。刷新令牌必须仅使用 TLS 传输,并具有 [RFC2818] 定义的服务器身份验证。
每当可以验证客户端身份时,授权服务器必须验证刷新令牌和客户端身份之间的绑定。当无法进行客户端身份验证时,授权服务器应该部署其他方法来检测刷新令牌滥用。
例如,授权服务器可以使用刷新令牌轮换,其中每个访问令牌刷新响应都会发出一个新的刷新令牌。先前的刷新令牌已失效但由授权服务器保留。如果刷新令牌被破坏并随后被攻击者和合法客户端使用,其中之一将提供无效的刷新令牌,这将通知授权服务器该漏洞。
授权服务器必须确保未授权方无法生成、修改或猜测刷新令牌以生成有效的刷新令牌。