目录
一、简介
二、角色
二、协议流程
三、授权许可
1、授权码
2、隐式许可
3、资源所有者密码凭据
4、客户端凭据
四、访问令牌
五、刷新令牌
六、TLS版本
七、HTTP重定向
八、互操作性
九、符号约定
一、简介
在传统的客户端-服务器身份验证模式中,客户端请求服务器上访问受限的资源(受保护的资源)时,需要使用资源所有者的凭据在服务器上进行身份验证。
资源所有者为了给第三方应用提供受限资源的访问权限,需要与第三方共享它的凭据。这就导致一些问题和局限:
- 第三方应用需要存储资源所有者的凭据以供将来使用。该凭据通常是明文密码。
- 服务器需要支持密码身份认证,尽管密码认证有固有的安全缺陷。
- 第三方应用获得了对资源所有者的受保护资源的过于宽泛的访问权限,从而导致资源所有者不能限制对资源的有限子集的访问时限或权限。
- 资源所有者不能撤销某个第三方的访问权限而不影响其它第三方,并且必须更改他们的密码才能做到。
- 与任何第三方应用的妥协导致对终端用户的密码及该密码所保护的所有数据的妥协。
OAuth通过引入授权层以及从资源所有者角色分离出客户端角色来解决这些问题。在OAuth中,客户端请求对受资源所有者控制且托管在资源服务器上的资源的访问权限,并授予一组不同于资源所有者所拥有的凭据。
作为使用资源所有者的凭据访问受保护资源的替代,客户端获得一个访问令牌———一个代表特定作用域、生命周期以及其他访问权限属性的字符串。访问令牌由授权服务器在资源所有者认可的情况下颁发给第三方客户端。客户端使用访问令牌访问托管在资源服务器上的受保护资源。
例如,终端用户(资源所有者)可以许可一个打印服务(客户端)访问她存储在图片分享网站(资源服务器)上的受保护图片,而无需与打印服务分享自己的用户名和密码,而是,她直接与图片分享网站信任的服务器(授权服务器)进行身份验证,该服务器颁发给打印服务具体的委托凭据(访问令牌)。
本规范是为HTTP([RFC2616][RFC2616])协议设计的。在任何非HTTP协议上使用OAuth不在本规范的范围之内。
OAuth 1.0协议([RFC5849][RFC5849])作为一个指导性文档发布,是一个小的特设团体的工作成果。本标准化规范在OAuth 1.0的部署经验之上构建,也包括从更广泛的IETF社区收集到其他用户案例和可扩展性需求。OAuth 2.0协议不向后兼容OAuth 1.0。这两个版本可以在网络上共存,实现者可以选择同时支持他们。然而,本规范的用意是新的实现按本文档的规定支持Auth 2.0,OAuth 1.0仅用于支持现有的部署。OAuth 2.0协议与OAuth 1.0协议实现细节没有太多关联。熟悉OAuth 1.0的实现者应该理解本文档,而非对有关OAuth 2.0的结构和细节做任何假设。
二、角色
OAuth定义了四种角色:
-
资源所有者
能够许可对受保护资源的访问权限的实体。当资源所有者是个人时,它被称为最终用户。
-
资源服务器
托管受保护资源的服务器,能够接收和响应使用访问令牌对受保护资源的请求。
-
客户端
使用资源所有者的授权代表资源所有者发起对受保护资源的请求的应用程序。术语“客户端”并非特指任何特定的的实现特点(例如:应用程序是否是在服务器、台式机或其他设备上执行)。
-
授权服务器
在成功验证资源所有者且获得授权后颁发访问令牌给客户端的服务器。
授权服务器和资源服务器之间的交互超出了本规范的范围。授权服务器可以和资源服务器是同一台服务器,也可以是分离的个体。一个授权服务器可以颁发被多个资源服务器接受的访问令牌。
二、协议流程
+--------+ +---------------+
| |--(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 ---| |
+--------+ +---------------+
图1:抽象的协议流程
图1中所示的抽象的OAuth 2.0流程描述了四种角色之间的交互,包括以下步骤:
- (A)客户端从资源所有者处请求授权。授权请求可以直接向资源所有者发起(如图所示),或者更可取的是通过授权服务器作为中介间接发起。
- (B)客户端收到授权许可,这是一个代表资源所有者的授权的凭据,使用本规范中定义的四种许可类型之一或者使用扩展许可类型表示。授权许可类型取决于客户端请求授权所使用的方法以及授权服务器支持的类型。
- (C)客户端与授权服务器进行身份认证并出示授权许可以请求访问令牌。
- (D)授权服务器验证客户端身份并验证授权许可,若有效则颁发访问令牌。
- (E)客户端从资源服务器请求受保护资源并出示访问令牌进行身份验证。
- (F)资源服务器验证访问令牌,若有效则处理该请求。
客户端从资源所有者获得授权许可(步骤(A)和(B)所示)的更好方法是使用授权服务器作为中介,如4.1节图3所示。
三、授权许可
授权许可是一个代表资源所有者授权(访问受保护资源)的凭据,客户端用它来获取访问令牌。本规范定义了四种许可类型——授权码、隐式许可、资源所有者密码凭据和客户端凭据——以及用于定义其他类型的可扩展性机制。
1、授权码
授权码通过使用授权服务器做为客户端与资源所有者的中介而获得。客户端不是直接从资源所有者请求授权,而是引导资源所有者至授权服务器(由在[RFC2616][RFC2616]中定义的用户代理),授权服务器之后引导资源所有者带着授权码回到客户端。
在引导资源所有者携带授权码返回客户端前,授权服务器会鉴定资源所有者身份并获得其授权。由于资源所有者只与授权服务器进行身份验证,所以资源所有者的凭据不需要与客户端分享。
授权码提供了一些重要的安全益处,例如验证客户端身份的能力,以及向客户端直接的访问令牌的传输而非通过资源所有者的用户代理来传送它而潜在暴露给他人(包括资源所有者)。
2、隐式许可
隐式许可是为用如JavaScript等脚本语言在浏览器中实现的客户端而优化的一种简化的授权码流程。在隐式许可流程中,不再给客户端颁发授权码,取而代之的是客户端直接被颁发一个访问令牌(作为资源所有者的授权)。这种许可类型是隐式的,因为没有中间凭据(如授权码)被颁发(之后用于获取访问令牌)。
当在隐式许可流程中颁发访问令牌时,发授权服务器不对客户端进行身份验证。在某些情况下,客户端身份可以通过用于向客户端传送访问令牌的重定向URI验证。访问令牌可能会暴露给资源所有者,或者对资源所有者的用户代理有访问权限的其他应用程序。
隐式许可提高了一些客户端(例如一个作为浏览器内应用实现的客户端)的响应速度和效率,因为它减少了获取访问令牌所需的往返数量。然而,这种便利应该和采用隐式许可的安全影响作权衡,如那些在10.3和10.6节中所述的,尤其是当授权码许可类型可用的时候。
3、资源所有者密码凭据
资源所有者密码凭据(即用户名和密码),可以直接作为获取访问令牌的授权许可。这种凭据只能应该当资源所有者和客户端之间具有高度信任时(例如,客户端是设备的操作系统的一部分,或者是一个高度特权应用程序),以及当其他授权许可类型(例如授权码)不可用时被使用。
尽管本授权类型需要对资源所有者凭据直接的客户端访问权限,但资源所有者凭据仅被用于一次请求并被交换为访问令牌。通过凭据和长期有效的访问令牌或刷新令牌的互换,这种许可类型可以消除客户端存储资源所有者凭据供将来使用的需要。
4、客户端凭据
当授权范围限于客户端控制下的受保护资源或事先与授权服务器商定的受保护资源时客户端凭据可以被用作为一种授权许可。典型的当客户端代表自己表演(客户端也是资源所有者)或者基于与授权服务器事先商定的授权请求对受保护资源的访问权限时,客户端凭据被用作为授权许可。
四、访问令牌
访问令牌是用于访问受保护资源的凭据。访问令牌是一个代表向客户端颁发的授权的字符串。该字符串通常对于客户端是不透明的。令牌代表了访问权限的由资源所有者许可并由资源服务器和授权服务器实施的具体范围和期限。
令牌可以表示一个用于检索授权信息的标识符或者可以以可验证的方式自包含授权信息(即令牌字符串由数据和签名组成)。额外的身份验证凭据——在本规范范围以外——可以被要求以便客户端使用令牌。
访问令牌提供了一个抽象层,用单一的资源服务器能理解的令牌代替不同的授权结构(例如,用户名和密码)。这种抽象使得颁发访问令牌比颁发用于获取令牌的授权许可更受限制,同时消除了资源服务器理解各种各样身份认证方法的需要。
基于资源服务器的安全要求访问令牌可以有不同的格式、结构及采用的方法(如,加密属性)。访问令牌的属性和用于访问受保护资源的方法超出了本规范的范围,它们在RFC6750等配套规范中定义。
五、刷新令牌
刷新令牌是用于获取访问令牌的凭据。刷新令牌由授权服务器颁发给客户端,用于在当前访问令牌失效或过期时,获取一个新的访问令牌,或者获得相等或更窄范围的额外的访问令牌(访问令牌可能具有比资源所有者所授权的更短的生命周期和更少的权限)。颁发刷新令牌是可选的,由授权服务器决定。如果授权服务器颁发刷新令牌,在颁发访问令牌时它被包含在内(即图1中的步骤D)。
刷新令牌是一个代表由资源所有者给客户端许可的授权的字符串。该字符串通常对于客户端是不透明的。该令牌表示一个用于检索授权信息的标识符。不同于访问令牌,刷新令牌设计只与授权服务器使用,并不会发送到资源服务器。
+--------+ +---------------+
| |--(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 +---------------+
图2:刷新过期的访问令牌
图2中的所示流程包含以下步骤:
- (A)客户端通过与授权服务器进行身份验证并出示授权许可请求访问令牌。
- (B)授权服务器对客户端进行身份验证并验证授权许可,若有效则颁发访问令牌和刷新令牌。
- (C)客户端通过出示访问令牌向资源服务器发起受保护资源的请求。
- (D)资源服务器验证访问令牌,若有效则满足该要求。
- (E)步骤(C)和(D)重复进行,直到访问令牌到期。如果客户端知道访问令牌已过期,跳到步骤(G),否 则它将继续发起另一个对受保护资源的请求。
- (F)由于访问令牌是无效的,资源服务器返回无效令牌错误。
- (G)客户端通过与授权服务器进行身份验证并出示刷新令牌,请求一个新的访问令牌。客户端身份验证要求基于客户端的类型和授权服务器的策略。
- (H)授权服务器对客户端进行身份验证并验证刷新令牌,若有效则颁发一个新的访问令牌(和——可选地——一个新的刷新令牌)。
步骤(C)、(D)、(E)和(F)在本规范的范围以外,第七节中中所述。
六、TLS版本
本规范任何时候使用传输层安全性(TLS),基于广泛的部署和已知的安全漏洞TLS的相应版本(或多个版本)将会随时间而变化。在本规范撰写时,TLS 1.2版RFC5246是最新的版本,但它具有非常局限的部署基础,可能还未准备好可以实现。TLS 1.0版RFC2246是部署最广泛的版本并将提供最宽泛的互操作性。
实现也可以支持满足其安全需求的其他传输层安全机制。
七、HTTP重定向
本规范广泛采用了HTTP重定向,有此客户端或授权服务器引导资源所有者的用户代理到另一个目的地址。虽然本规范中的例子演示了HTTP 302状态码的使用,但是任何其他通过用户代理完成重定向的方法都是允许的并被考虑作为实现细节。
八、互操作性
OAuth 2.0提供了丰富的具有明确的安全性质的授权框架。然而,尽管在其自身看来是一个带有许多可选择组件的丰富且高度可扩展的框架,本规范有可能产生许多非可互操作的实现。
此外,本规范中留下一些必需组件部分或完全没有定义(例如,客户端注册、授权服务器性能、端点发现等)。没有这些组件,客户端必须针对特定的授权服务器和资源服务器被手动并专门配置,以进行互操作。
本框架设计具有一个明确的期望,即未来工作将定义实现完整的web范围的互操作性所需的规范性的配置和扩展。
九、符号约定
本规范中的关键词“必须”、“不能”、“必需的”、“要”、“不要”、“应该”、“不应该”、“推荐的”、“可以”以及“可选的”按RFC2119所述解释。
本规范使用RFC5234的扩展巴科斯-诺尔范式(ABNF)表示法。此外,来自“统一资源标识符(URI):通用语法”RFC3986的规则URI引用也包含在内。
某些安全相关的术语按照RFC4949中定义的意思理解。这些术语包括但不限于:“攻击”、“身份认证”、“授权”、“证书”、“机密”,“凭据”,“加密”,“身份”,“记号”,“签名”,“信任”,“验证”和“核实”。
除非另有说明,所有协议参数的名称和值是大小写敏感的。