OAuth2.0 授权框架


OAuth2.0是在互联网中广泛使用的一个授权协议,该规范用于取代OAuth1.0,但2.0并不兼容1.0OAuth2.0的协议标准为:RFC 6749,实现非常简单清晰。OAuth2.0用于授权第三方应用,获取对受限制HTTP服务的访问权限。我们在网页或Web中常见“QQ登录”、“微博登录”、“微信登录”等,都是OAuth2.0规范实现。

1. 简介

在传统的客户端-服务器认证模式中,客房端要访问受限制(受保护)的资源,服务器需要验证资源所有者的凭据。为了提供第三方应用所访问的受限资源,资源所有者需要与第三方共享凭据。这样,势必会带来一些问题和局限性:

  • 第三方应用为了之后能够使用,需要存储资源所有者的凭据,而凭据通常是一个明文保存的密码。
  • 服务器需要支持密码认证,尽管密码存在一些安全漏洞。
  • 第三方应用获得了对受保护资源的过多的访问权限,离开资源所有者没有任何能力去限制访问时长或访问有限的资源子集。
  • 资源所有者不能单独撤消某个第三方访问者的访问权限,而需要撤消所有访问者的访问权限,且必须通过修改密码来访问撤消。
  • 与任何第三方应用程序让步都会导致最终用户的密码和所有受该密码保护的数据的让步。

为了解决这些问题,OAuth引入了一个授权层,用于从资源所有者中分离客户端角色。在OAuth中,客户端要请求访问的资源受资源所有者且由资源服务器托管,并由资源所有者发了一组不同权限的凭据集。

与使用资源所有的者凭据访问受限资源的方式有所不同,客户端需要获取一个访问令牌(access token)--一指定了作用域、生命周期及其它访问属性的字符串。访问令牌由授权服务器在资源所有者认可的情况下颁发给第三方客户端。客户端通过获取访问令牌,访问托管在资源服务器上的受保护资源。


1.1 角色

在OAuth授权体系当中,定义了以下四4中角色:

  • 资源所有者(Resource Owner) - 具有准许访问受保护资源权限的实体。当资源所有者是一个人时,称之为最终用户。
  • 资源服务器(Resource Server) - 托管受保护资源的服务器,能够接收和响应使用访问令牌的受保护资源访问请求。
  • 客户端(Clint) - 在一个资源所有者的授权后,发起对受保护资源访问请求的应用程序,即第三方应用
  • 授权服务器(Authorization Server) - 提供认证服务的服务器。在验证资源所有者且获得访问授权后,颁发访问令牌给客户端。

其中,授权服务器资源服务器可以是同一台服务器,也可以是独立的服务器。而一个授权服务器也可以为多个资源服务器提供访问令牌。

1.2 协议流程

 +--------+                               +---------------+
 |        |--(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 ---|               |
 +--------+                               +---------------+

如上所示,在OAuth2.0中4种角色之间的交互包含以下步骤:

  • (A)客户端向资源所有者请求授权。授权请求可以直接向资源所有者发起(如图所示),或是通过授权服务器作为中介间接发起。
  • (B)客户端收到授权许可,这个许可就代表资源所有者的授权的凭据。
  • (C)客户端通过获取的授权许可,向授权服务器申请访问令牌。
  • (D)授权服务器验证客户端身份及授权许可,验证通过后颁发访问令牌。
  • (E)客户端使用访问令牌向资源服务器请求受保护资源。
  • (F)资源服务器验证访问令牌,验证有效则处理该请求。

1.3 授权许可(类型)

授权许可是一个代表资源所有者授权(访问受保护资源)的凭据,客户端用它来获取访问令牌。OAuth2.0共定义了4种许可类型(授权码、隐式授权、密码授权、客户端凭据),并定义了许可类型的扩展机制。

授权码

授权码通过使用授权服务器做为客户端与资源所有者的中介而获取,客户端不是直接从资源所有者请求授权,而是引导资源所有者至授权服务器,获取授权服务器授权之后再引导资源所有者带着授权码返回客户端。

在引导资源所有者携带授权码返回客户端前,授权服务器会鉴定资源所有者身份并获得其授权。由于资源所有者只与授权服务器进行身份验证,所以资源所有者的凭据不需要与客户端分享。

授权码提供了一些比较重要的安全方面的好处,如验证客户端身份的能力,以及向客户端直接的访问令牌的传输,而非通过资源所有者的用户代理来传送,从而降低了潜在暴露给他人(包括资源所有者)的风险。

隐式授权许可

隐式许可是使用如JavaScript等脚本语言在浏览器中实现,为客户端使用方便而优化的一种简化的授权码流程。在隐式许可流程中,不再给客户端颁发授权码,取而代之的是向客户端直接颁发一个表示所有者授权的访问令牌。

在隐式授权许可流程中颁发访问令牌时,授权服务器不对客户端进行身份验证。在某些情况下,客户端可以通过向客户端传送访问令牌的重定向URI进行验证。访问令牌可能会暴露给资源所有者或对其用户代理有访问权限的其他应用。

隐式许可提高了一些客户端的响应速度和效率,因为它减少了获取访问令牌所需的往返次数。然而,这种便利应该和采用隐式许可的安全影响作权衡。

密码凭据授权

使用资源所有者密码凭据(用户名和密码),直接作为获取访问令牌的授权许可。这种凭据获取方式只适用于资源所有者和客户端之间具有高信任度时(如,客户端是设备的操作系统的一部分,或是一个高度特权应用程序),以及其他授权许可类型不可用时使用。

虽然这种授权类型使客户端获取了资源所有者凭据的访问权限,但仅用于交换访问令牌时的一次请求。其后都是基于长期有效的访问令牌或刷新令牌,因此在这种授权许可中,可以清除客户端的凭据存储。

客户端凭据

当授权范围限制于客户端控制下的受保护资源(如:当客户端同时也是资源所有者),或事先与授权服务器定义受保护资源时,将客户端凭据作为一种授权许可。

1.4 访问令牌

访问令牌(Access Token)是用于访问受保护资源的凭据。访问令牌是一个向客户端颁发的代表授权的字符串。该字符串通常对于客户端是不透明的。令牌表示由资源所有者授予的访问权限的指定范围和持续时间,并由资源服务器和授权服务器执行。

令牌可以表示一个用于检索授权信息的标识符或者是一个包含授权信息的可验证字符串(即令牌字符串由数据和签名组成)。

访问令牌提供了一个抽象层,用单一的资源服务器能理解的令牌代替不同的授权结构(例如,用户名和密码)。这种抽象使得颁发访问令牌比颁发用于获取令牌的授权许可更受限制,同时消除了资源服务器理解各种各样身份认证方法的需要。

基于资源服务器的安全要求,访问令牌可以有不同的格式、结构及方法(如,加密属性)。访问令牌的属性及访问受保护资源的方法在RFC6750等配套规范中定义。

1.5 刷新令牌

刷新令牌(Refresh Token)是用于获取访问令牌的凭据。刷新令牌由授权服务器颁发给客户端,用于在当前访问令牌失效或过期时,获取一个新的访问令牌,或者获得相等或更窄范围的额外的访问令牌(访问令牌可能比资源所有者所授权的生命周期更短或者权限更少)。是否颁发刷新令牌是可选的,由授权服务器决定。如果授权服务器颁发刷新令牌,在颁发访问令牌时它会被包含在内协议流程-步骤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        +---------------+

如上所示,是过期访问令牌的刷新流程,在这个流程中包含以下步骤:

  • (A)客户端通过授权许可向授权服务器请求访问令牌。
  • (B)授权服务器对客户端进行身份及授权许可验证,若有效则颁发访问令牌和刷新令牌。
  • (C)客户端通访问令牌向资源服务器请求受保护的资源。
  • (D)资源服务器验证访问令牌,若有效则满足该要求。
  • (E)步骤(C)和(D)重复进行,直到访问令牌到期,如果客户端知道访问令牌已过期,跳到步骤(G)。
  • (F)由于访问令牌是无效,资源服务器返回无效令牌错误。
  • (G)客户端通过刷新令牌向授权服务器请求新的访问令牌。客户端身份验证要求基于客户端的类型和授权服务器的策略。
  • (H)授权服务器对客户端进行身份验证并验证刷新令牌,验证通过则颁发一个新的访问令牌(和一个新的刷新令牌--可选)。

1.6 TLS版本

本规范任何时候使用安全传输层协议(TLS),其适用的TLS版本及当前版的部署及已知的安全漏洞,会由于时间的不同而不同。在本规范撰写时,TLS 1.2版RFC5246是最新的版本,但它的就用很有局限性。而TLS 1.0版RFC2246是应用最广泛的版本,并将提供最广泛的互操作性。


2. 客户端注册

在开始协议前,客户端应在授权服务器注册。客户端注册不要求客户端与授权服务器之间直接交互。在授权服务器支持时,注册可以依靠其他方式来建立信任关系并获取客户端的属性(如重定向URI、客户端类型)。例如,注册可以使用自发行或第三方发行声明或通过授权服务器使用信任通道执行客户端发现完成。

2.1 客户端类型

根据客户端维持凭据机密性的能力,OAuth定义了两种客户端类型:

  • 机密客户端 - 能够维持其凭据机密性(如客户端执行在具有对客户端凭据有限访问权限的安全服务器上),或者能够使用 其他方式保证客户端身份验证的安全性。
  • 公开客户端 - 不能够维持其凭据的机密性(如客户端执行在由资源所有者使用的设备上,例如已安装的本地应用程序或基于Web浏览器的应用),且不能通过其他方式保证客户端身份验证的安全性。

2.2 客户端标识

授权服务器颁发给已注册客户端客户端标识——一个代表客户端提供的注册信息的唯一字符串。客户端标识不是一个秘密,它暴露给资源所有者并且不能单独用于客户端身份验证。客户端标识对于授权服务器是唯一的。

客户端的字符串大小未在OAuth2.0中定义。客户端应该避免对标识大小做假设。授权服务器应记录其发放的任何标识的大小。

2.3 客户端身份验证

如果客户端类型是加密的,客户端和授权服务器应建立适合于授权服务器的安全性要求的客户端身份验证方法。授权服务器可以接受符合其安全要求的任何形式的客户端身份验证。

机密客户端通常颁发(或建立)一组客户端凭据用于与授权服务器进行身份验证(如,密码、公/私钥对)。授权服务器可以与公共客户端建立客户端身份验证方法,但是,授权服务器不能依靠公共客户端身份验证达到识别客户端的目的。

客户端在每次请求中不能使用一个以上的身份验证方法。

客户端密码

有客户端密码的客户端可以使用HTTP基本身份验证方案(RFC2617中定义)与授权服务器进行身份验证。客户端标识使用“application/x-www-form-urlencoded”编码方式对用户名和密码进行编码。授权服务器必须支持HTTP基本身份验证方案,用于客户端的身份。例如:

Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3

此外,授权服务器可以使用下列参数,在请求正文(请求体)中包含客户端凭据:

  • client_id - 必需。如2.2节所述的注册过程中颁发给客户端的客户端标识。
  • client_secret - 必需。客户端秘钥,如果客户端密钥为空字符串可以忽略该参数。

不建议在请求正文中使用这两个参数包含客户端凭据,仅应限于不能直接采用HTTP基本身份验证的方案中。参数只能在请求正文中发送,不能包含在请求URI中。

例如,使用请求正文参数请求刷新访问令牌:

 POST /token HTTP/1.1
 Host: server.example.com
 Content-Type: application/x-www-form-urlencoded
 grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA&client_id=s6BhdRkqt3&client_secret=7Fjfp0ZBr1KtDRbnfVdmIw

当使用密码身份验证发送请求时,授权服务器必须要求使用TLS。

由于该客户端身份验证方法包含密码,授权服务器必须保护所有使用到密码的终端免受暴力攻击。

其他身份验证方法

授权服务器可以支持任何与其安全要求匹配的合适的HTTP身份验证方案。当使用其他身份验证方法时,授权服务器必须定义客户端标识(注册记录)和认证方案之间的映射关系。

2.4 未注册的客户端(Unregistered Clients)

本规范不排除使用未注册的客户端。然而,使用这样的客户端超出了本规范的范围,且需要额外的安全性分析并审查其互操作性影响。


3. 协议端点(protocol endpoints)

授权过程采用了两种授权服务器端点(HTTP资源):

  • 授权端点——用于从资源所有者获取授权后,客户端用户代理的重定向。
  • 令牌端点——用于客户端将授权许可交换为访问令牌,通常需要客户端身份验证。

以及一种客户端端点

  • 重定向端点——用于授权服务器通过资源所有者的用户代理,向客户端返回含有授权凭据的响应。

并不是每种授权许可类型都采用两种端点。扩展许可类型可以按需定义其他端点。

3.1 授权端点(Authorization Endpoint)

授权端点用于与资源所有者交互获取授权许可。授权服务器必须先验证资源所有者的身份。授权服务器对资源所有者进行身份验证的方式(如,用户名和密码登录、会话cookies)超出了本规范的范围。

客户端通过何种方式获得授权端点的位置超出了本文档范围,但该位置通常在服务文档中提供。

端点URI可以包含“application/x-www-form-urlencoded”格式(按附录B)的查询部分([RFC3986] 3.4节),当添加额外的查询参数时必须保留该部分。端点URI不得包含片段部分。

除非授权服务器对于授权端点必须支持使用HTTP“GET”方法,也可以支持使用“POST”的方法。

发送没有值的参数时,必须将它们从请求中省略。授权服务器必须忽略不能识别的请求参数。请求和响应参数不能包含超过一次。

3.1.1 响应类型

授权端点被用于授权码许可类型和隐式许可类型流程。客户端使用以下参数通知授权服务器期望的许可类型:

  • response_type - 必需。其值是如4.1.1节所述,用于请求授权码的“code”;如4.2.1节所述,用于请求访问令牌的“token”(隐式许可)或者如8.4节所述的一个注册的扩展值之中的一个。

扩展响应类型是一个以空格(%x20)分隔的值的列表,值的顺序并不重要(例如,响应类型“a b”与“b a”相同)。 这样的复合响应类型的含义由其各自的规范定义。

如果授权请求缺少“response_type”参数,或者如果响应类型不可解析,授权服务器必须返回一个4.1.2.1所述的响应错误。

3.1.2 重定向端点

在完成与资源所有者的交互后,授权服务器引导资源所有者的用户代理返回到客户端。授权服务器重定向用户代理至客户端的重定向端点,该端点是事先在客户端注册过程中或者当发起授权请求时与授权服务器建立的。

重定向端点URI必须是如RFC3986的3.4节所述的绝对URI。端点URI可以包含“application/x-www-form-urlencoded”编码的查询字符串部分(RFC3986的3.4节),当添加额外的查询参数时必须保留该部分。端点URI不得包含片段部分。

3.2 令牌端点(Token Endpoint)

用于客户端通过授权许可(authorization grant)或刷新令牌(refresh token)来获取访问令牌(access token)。令牌端点被用于除了隐式许可类型(因为访问令牌是直接颁发的)外的每种授权许可中。

端点URI可以包含“application/x-www-form-urlencoded”格式的查询字符串。客户端必须使用HTTP“POST”方法。

发送的没有值的参数,必须在请求中省略。授权服务器必须忽略不能识别的请求参数。请求和响应参数不能包含超过一次。

3.3 访问令牌范围(Access Token Scope)

授权端点和令牌端点允许客户端使用scope请求参数,指定请求的访问范围。相反,授权服务器也可以使用scope响应参数,通知客户端颁发的访问令牌的可访问范围。

scope参数值是以空格分隔的、大小写敏感的字符串。该字符串由授权服务器定义。当其包含多个空格分隔时,其顺序并不重要,且要为每个字符串添加一个的访问区域。

scope = scope-token *( SP scope-token )
scope-token = 1*( %x21 / %x23-5B / %x5D-7E )

授权服务器根据授权策略或资源拥有者的要求,可以全部或部分忽略客户端请求的范围。如果客户端请求及颁发的访问令牌实际可访问范围不同,授权服务器必须在scope响应参数中通知客户端实际的许可范围。

如果客户端请求授权时忽略了范围参数,授权服务器或者使用预定义范围处理请求,或者使请求失败以指出无效范围。


4. 获取授权

为了获取访问令牌,客户端首先要从资源所有者那里获得授权。授权表现形式为授权许可(Guthorization Grant),客户端使用它来请求访问令牌。OAuth定义了四种许可类型:授权码、隐式许可、资源所有者密码凭据和客户端凭据。它还提供了用于定义其他许可类型的扩展机制。

4.1 授权码许可(Authorization Code Grant)

授权码许可类型用于获取访问令牌和刷新令牌,并且为受信任的客户端进行了优化。由于这是一个基于重定向的流程,客户端必须能够与资源所有者的用户代理(通常是Web浏览器)进行交互,并能够接收来自授权服务器的传入请求(通过重定向)。

授权码流程:

 +----------+
 | 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)客户端通过向授权端点,引导资源所有者的用户代理开始流程。客户端请求中包括客户端标识、请求范围、本地状态和重定向URI,一旦访问被许可(或拒绝)授权服务器将传送用户代理回到该URI。
  • (B)授权服务器验证资源拥有者的身份(通过用户代理),并确定资源所有者是否允许或拒绝客户端的访问请求。
  • (C)假设资源所有者许可访问,授权服务器使用之前(在请求时或客户端注册时)提供的重定向URI,重定向用户代理回到客户端。重定向URI包括授权码和之前客户端提供的任何本地状态。
  • (D)客户端通过包含上一步中收到的授权码从授权服务器的令牌端点请求访问令牌。当发起请求时,客户端与授权服务器进行身份验证。客户端包含用于获取授权码的重定向URI来用于验证。
  • (E)授权服务器对客户端进行身份验证,验证授权码,并确保接收的重定向URI与在步骤(C)中用于重定向(资源所有者的用户代理)到客户端的URI相匹配。如果通过,授权服务器响应返回访问令牌与可选的刷新令牌。

4.1.1 授权请求(Authorization Request)

客户端使用'application/x-www-form-urlencoded'编码的URI向授权端点发起授权请求,在请求的查询字符串部分包含以下参数:

  • response_type - 必需。值必须被设置为code
  • client_id - 必需。如2.2节所述的客户端标识。
  • redirect_uri - 可选。如3.1.2节所述的重定向URI。
  • scope - 可选。请求的范围,如3.3节所述的访问。
  • state - 推荐。客户度用于维护请求和回调之间的状态,一个不透明的值。当重定向用户代理回到客户端时,授权服务器必须包含此值。该参数应该用于防止如10.12所述的跨站点请求伪造。

客户端使用HTTP重定向响应向构造的URI定向资源所有者,或者通过经由用户代理至该URI的其他可用方法。 例如,客户端使用TLS定向用户代理发起下述HTTP请求:

GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com

授权服务器应该验证该请求,确保提交参数的有效性。如果请求是有效,授权服务器应该对资源所有者进行身份验证,并获取授权决定(通过询问资源所有者或通过经由其他方式确定批准)。

当确定决定后,授权服务器使用HTTP重定,将响应重定向到客户端提供重定向URI。

4.1.2 授权响应(Authorization Response)

如果资源所有者允许访问请求,授权服务器颁发授权码,通过'application/x-www-form-urlencoded'编码的重定向URI将授权码传递到客户端,在URI的查询字符部分中使用以下两个参数传递授权码:

  • code - 必需。授权服务器生成的授权码。

    授权码必须在颁发后很快过期以减小泄露风险,推荐的最长的授权码生命周期是10分钟。客户端不能使用授权码超过一次。如果一个授权码被使用一次以上,授权服务器必须拒绝该请求并应该撤销先前可能发出的基于该授权码的所有令牌。授权码与客户端标识和重定向URI绑定。

  • state - 必需。如果客户端授权请求中包含state参数,则从客户端接收这个确且值。

例如,授权服务器通过发送以下HTTP响应重定向用户代理:

HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyz

客户端必须忽略无法识别的响应参数。OAUTH未定义授权码字符串大小。客户端应该避免假设代码值的长度,授权服务器应记录其发放的任何值的大小。

4.1.3 访问令牌请求(Access Token Request)

客户端以'application/x-www-form-urlencoded'编码格式,在HTTP请求体中向令牌端点发送UTF-8编码的下列参数:

  • grant_type - 必需。值必须被设置为'authorization_code'
  • code - 从授权服务器收到的授权码。
  • redirect_uri - 必需。若'redirect_uri'参数为4.1.1节所述包含在授权请求中,且他们的值必须相同。
  • client_id - 必需。如果客户端没有如3.2.1节所述与授权服务器进行身份认证。

例如,客户端使用TLS发起如下的HTTP请求:

POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb

授权服务器必须:

  • 要求机密客户端或任何被颁发了客户端凭据(或有其它身份验证要求)的客户端进行客户端身份验证
  • 若包括了客户端身份验证,则验证客户端身份
  • 确保授权码颁发给了通过身份验证的加密客户端,或者如果客户端是公开的,确保代码颁发给了请求中的'client_id'
  • 验证授权码是有效的,并确保提供了redirect_uri参数,若redirect_uri参数参数如4.1.1所述包含在初始授权请求中,应确保它们的值是相同的。

4.1.4 请求令牌响应(Access Token Response)

如果访问令牌请求有效且已被授权,授权服务器就应如5.1节所述颁发“访问令牌”以及可选的“刷新令牌”。如果请求客户端身份验证失败或无效,授权服务器就应如5.2节所述返回错误响应。

以下是一个正确响应的示例:

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
  "access_token":"2YotnFZFEjr1zCsicMWpAA",
  "token_type":"example",
  "expires_in":3600,
  "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
  "example_parameter":"example_value"
}


4.2 隐式授权许可

隐式授权类型用于获取访问令牌(不支持发行刷新令牌),并对已知操作的具体重定向URI的公共客户端进行优化。这些客户端通常在浏览器中使用如JavaScript的脚本语言实现。

由于这是一个基于重定向的流程,客户端必须能够与资源所有者的用户代理(通常是Web浏览器)进行交互并能够接收来自授权服务器的传入请求(通过重定向)。

不同于客户端分为请求授权和访问令牌的授权码许可类型,客户端收到的授权请求结果是访问令牌。

隐式许可类型不包含客户端身份验证而依赖于资源所有者在场和重定向URI的注册。因为访问令牌被编码到重定向URI中,它可能会暴露给资源所有者和与客户端相同设备上的其它应用。

+----------+
 | 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 |
 |         |
 +---------+

注:说明步骤(A)和(B)的直线因为通过用户代理而被分为两部分。

如以上隐式许可流程中所示,流程包含以下步骤:

  • (A)客户端通过向授权端点引导资源所有者的用户代理开始流程。客户端包括它的客户端标识、请求范围、本地状态和重定向URI,一旦访问被许可(或拒绝)授权服务器将传送用户代理回到该URI。
  • (B)授权服务器验证资源拥有者的身份(通过用户代理),并确定资源所有者是否授予或拒绝客户端的访问请求。
  • (C)假设资源所有者许可访问,授权服务器使用之前(在请求时或客户端注册时)提供的重定向URI重定向用户代理回到客户端。重定向URI在URI片段中包含访问令牌。
  • (D)用户代理向重定向指示的Web托管的客户端资源发起请求(按RFC2616该请求不包含片段)。用户代理在本地保留片段信息。
  • (E)Web托管的客户端资源返回一个网页(通常是带有嵌入式脚本的HTML文档),该网页能够访问包含用户代理保留的片段的完整重定向URI并提取包含在片段中的访问令牌(和其他参数)。
  • (F)用户代理在本地执行Web托管的客户端资源提供的提取访问令牌的脚本。
  • (G)用户代理传送访问令牌给客户端。

4.2.1 授权请求

客户端使用"application/x-www-form-urlencoded"格式,向授权端点URI的查询部分添加以下请求参数:

  • response_type:必需。值必须设置为'token'
  • client_id:必需。如2.2节所述的客户端标识。
  • redirect_uri:可选。如3.1.2节所述。
  • scope:可选。如3.3节所述的访问请求的范围。
  • state:推荐。客户端用于维护请求和回调之间的状态的不透明的值。当重定向用户代理回到客户端时,授权服务器包含此值。该参数应该用于防止如10.12所述的跨域请求伪造。

客户端使用HTTP重定向构造的URI定向资源所有者,或者通过由用户代理定向至该URI的其他可用方法。

例如,客户端使用TLS定向用户代理发起下述HTTP请求:

GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com

授权服务器应验证该请求,确保所有需要的参数已提交且有效。授权服务器必须验证它将重定向访问令牌的URI与如3.1.2节所述的客户端注册的重定向URI匹配。

如果请求是有效的,授权服务器对资源所有者进行身份验证并获得授权决定(通过询问资源所有者或通过其他方式确定授权)。

当确定授权后,授权服务器使用HTTP重定,或者通过用户代理到该URI的其他可行方法,向提供的客户端重定向URI用户代理进行响应。

4.2.2 访问令牌响应

如果资源所有者允许访问请求,则授权服务器颁发访问令牌,并使用"application/x-www-form-urlencoded"格式,通过向重定向URI的查询部分添加以下参数,将访问令牌传至客户端:

  • access_token - 必需。授权服务器颁发的访问令牌。
  • token_type - 必需。如7.1节所述的颁发的令牌的类型。值是大小写不敏感的。
  • expires_in - 推荐。以秒为单位的访问令牌生命周期。如,值'3600'表示访问令牌将在1小时后到期。如果省略,则授权服务器应该通过其他方式提供过期时间,或者记录默认值。
  • scope - 可选。若与客户端请求的范围相同,则不需提供,否则必需提供。如3.3节所述的访问令牌的范围。
  • state - 必需。'state'参数在客户端授权请求中提交。从客户端接收的精确值。授权服务器不能颁发刷新令牌。

如,授权服务器通过发送以下HTTP响应,重定向到用户代理:(

HTTP/1.1 302 Found
Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=example&expires_in=3600

开发人员应注意,一些用户代理不支持在HTTP'Location'响应头字段中包含查询部分。这些客户端需要使用除3xx以外重定向,将响应定向另一个客户端。如,返回一个HTML页面,并在其中包含一个链接,表现形式为重定向URI的动作的“继续”按钮。

客户端必须忽略无法识别的响应参数。本规范未定义授权码字符串大小。客户端应该避免假设代码值的长度。 授权服务器应记录其发放的任何值的大小。







5. 发放访问令牌







6. 刷新访问令牌







7. 访问受保护的资源







8. 可扩展性







9. 本地应用







10. 安全考虑







11. IANA考虑