oauth2.0

文档地址:https://datatracker.ietf.org/doc/html/rfc6749
译文地址:https://github.com/jeansfish/RFC6749.zh-cn
翻译整理:https://www.cnblogs.com/ctxsdhy/p/8355110.html

OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

OAuth 1.0已经是过去式,这里不讨论。这里仅讨论OAuth 2.0。

1. Introduction 简介

1.1. Roles 角色

OAuth定义了四种角色:

  • 资源所有者(resource owner):能够授予对受保护资源的访问权限的实体。当资源所有者是一个人时,称为最终用户(end-user)。
  • 资源服务器(resource server):托管受保护资源的服务器,能够接受并响应使用访问令牌的受保护资源请求。
  • 客户端(client):代表资源所有者发起受保护资源请求,并获得其授权的应用程序。"客户端"一词不涉及任何特定的实现特征(例如应用程序在服务器、桌面或其他设备上执行)。
  • 授权服务器(authorization server):在成功验证资源所有者并获得授权后,向客户端发放访问令牌的服务器。

授权服务器可以和资源服务器是同一台服务器,也可以是分离的个体。一个授权服务器可以颁发被多个资源服务器接受的访问令牌。

1.2. Protocol Flow 协议流程

     +--------+                               +---------------+
     |        |--(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.3. Authorization Grant 授权许可

4种授权方式

1.3.1. Authorization Code 授权码

  • 授权码通过使用授权服务器做为客户端与资源所有者的中介而获得。客户端不是直接从资源所有者请求授权,而是引导资源所有者至授权服务器(由在RFC2616中定义的用户代理),授权服务器之后引导资源所有者带着授权码回到客户端。
  • 在引导资源所有者携带授权码返回客户端前,授权服务器会鉴定资源所有者身份并获得其授权。由于资源所有者只与授权服务器进行身份验证,所以资源所有者的凭据不需要与客户端分享。
  • 授权码提供了一些重要的安全益处,例如验证客户端身份的能力,以及向客户端直接的访问令牌的传输而非通过资源所有者的用户代理来传送它而潜在暴露给他人(包括资源所有者)。

1.3.2. Implicit 隐式许可

  • 隐式许可是为用如JavaScript等脚本语言在浏览器中实现的客户端而优化的一种简化的授权码流程。在隐式许可流程中,不再给客户端颁发授权码,取而代之的是客户端直接被颁发一个访问令牌(作为资源所有者的授权)。这种许可类型是隐式的,因为没有中间凭据(如授权码)被颁发(之后用于获取访问令牌)。
  • 在隐式授权流程中,授权服务器不会对客户端进行身份验证。在某些情况下,可以通过传递访问令牌的重定向URI来验证客户端的身份。访问令牌可能会暴露给资源所有者或其他可以访问资源所有者用户代理的应用程序。
  • 隐式许可提高了一些客户端(例如一个作为浏览器内应用实现的客户端)的响应速度和效率,因为它减少了获取访问令牌所需的往返数量。然而,这种便利应该和采用隐式许可的安全影响作权衡,如那些在10.3和10.16节中所述的,尤其是当授权码许可类型可用的时候。

1.3.3. Resource Owner Password Credentials 资源所有者密码凭据

  • 资源所有者密码凭据(即用户名和密码),可以直接作为获取访问令牌的授权许可。这种凭据只能应该当资源所有者和客户端之间具有高度信任时(例如,客户端是设备的操作系统的一部分,或者是一个高度特权应用程序),以及当其他授权许可类型(例如授权码)不可用时被使用。
  • 尽管本授权类型需要对资源所有者凭据直接的客户端访问权限,但资源所有者凭据仅被用于一次请求并被交换为访问令牌。通过凭据和长期有效的访问令牌或刷新令牌的互换,这种许可类型可以消除客户端存储资源所有者凭据供将来使用的需要。

1.3.4. Client Credentials 客户端凭据

  • 当授权范围限制为受客户端控制的受保护资源,或者与授权服务器事先安排的受保护资源相关时,可以使用客户端凭据(或其他形式的客户端身份验证)作为授权授予。通常情况下,当客户端代表自身行事(客户端同时也是资源所有者),或者基于与授权服务器先前安排的授权请求对受保护资源进行访问时,会使用客户端凭据作为授权授予。

注意,不管哪一种授权方式,第三方应用申请令牌之前,都必须先到系统备案,说明自己的身份,然后会拿到两个身份识别码:客户端 ID(client ID)和客户端密钥(client secret)。这是为了防止令牌被滥用,没有备案过的第三方应用,是不会拿到令牌的。

1.4. Access Token 访问令牌

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

令牌可以是用于检索授权信息的标识符,也可以是以可验证方式自包含授权信息的令牌字符串(即由一些数据和签名组成的令牌字符串)。在客户端使用令牌时,可能需要额外的身份验证凭据,这超出了本规范的范围。

访问令牌提供了一个抽象层,用单个令牌取代了不同的授权构造(例如用户名和密码),该令牌可被资源服务器理解。这种抽象使得发放的访问令牌可以比用于获取它们的授权授予更加限制,并且无需资源服务器理解各种认证方法。

访问令牌可以根据资源服务器的安全要求具有不同的格式、结构和利用方式(例如,加密属性)。访问令牌的属性以及访问受保护资源的方法超出了本规范的范围,这些内容由伴随规范(如[RFC6750])定义。

1.5. Refresh Token 刷新令牌

刷新令牌是用于获取访问令牌的凭据。刷新令牌由授权服务器颁发给客户端,并用于在当前访问令牌失效或过期时获取新的访问令牌,或者获取具有相同或更窄范围的附加访问令牌(访问令牌的生命周期可能更短且权限更少,不超过资源所有者授权的权限)。授权服务器可以选择性地发放刷新令牌。如果授权服务器发放刷新令牌,它会在发放访问令牌时包含在内(即图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        +---------------+

Figure 2: Refreshing an Expired Access Token

图2中的所示流程包含以下步骤:

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

步骤(C)、(D)、(E)和(F)在本规范的范围以外,如第7节中所述。

2. Client Registration 客户端注册

2.2. Client Identifier 客户端标识

授权服务器向注册的客户端发放客户端标识符,该标识符是一个表示客户端提供的注册信息的唯一字符串。客户端标识符不是一个秘密,它会被公开给资源所有者,并且不能仅凭客户端标识符进行客户端身份验证。客户端标识符在授权服务器中是唯一的。

2.3. Client Authentication 客户端身份验证

2.3.1. Client Password 客户端密码

拥有客户端密码的客户端可以使用RFC2617中定义的HTTP基本身份验证方案与授权服务器进行身份验证。客户端标识使用按照附录B的“application/x-www-form-urlencoded”编码算法编码,编码后的值用作用户名;客户端密码使用相同的算法编码并用作密码。授权服务器必须支持HTTP基本身份验证方案,用于验证被颁发客户端密码的客户端的身份。格式:Basic <base64(client_id:client_secret)>。例如(额外的换行仅用于显示目的):
  Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3
虽然可以对 Basic Authentication 中的凭据进行加密处理,但这通常不是必需的,因为 Basic Authentication 主要用于身份验证而不是传输层的安全性。对于保护凭据的机密性,应该依赖于其他更适合的安全机制,如使用 HTTPS 协议和正确配置 OAuth 2.0 的各个组件。

此外,授权服务器可以使用下列参数支持在请求正文中包含客户端凭据:
  
client_id
  必需的。如2.2节所述的注册过程中颁发给客户端的客户端标识。
client_secret
  必需的。客户端秘密。 客户端可以忽略该参数若客户端秘密是一个空字符串。
    
使用这两个参数在请求正文中包含客户端凭据是不被建议的,应该限于不能直接采用HTTP基本身份验证方案(或其他基于密码的HTTP身份验证方案)的客户端。参数只能在请求正文中传送,不能包含在请求URI中。

例如,使用请求正文参数请求刷新访问令牌(第6节)(额外的换行仅用于显示目的):

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

当使用密码身份验证发送请求时,授权服务器必须要求使用如1.6所述的TLS。
由于该客户端身份验证方法包含密码,授权服务器必须保护所有使用到密码的端点免受暴力攻击。

3. Protocol Endpoints 协议端点

3.1. Authorization Endpoint 授权端点

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

授权端点是OAuth 2.0协议中的一个URL地址,用于进行用户身份验证和授权操作,用户在此处确认并授权客户端应用程序访问其受保护的资源。

用户在授权端点上确认并授权客户端应用程序后,授权服务器将生成一个授权码(Authorization Code)或访问令牌(Access
Token),用于后续客户端访问受保护资源时进行身份验证和授权。
 
授权端点的URL地址通常是在OAuth 2.0协议中定义的标准端点,例如
/authorize。然而,实际的授权端点URL可能会因不同的授权服务器实现而有所不同。

eg. 当用户在第三方应用程序中选择使用微信授权登录时,第三方应用程序将用户重定向到微信开放平台的授权端点。
授权端点的URL类似于以下示例:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=YOUR_APPID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

3.1.1. Response Type 响应类型

授权端点被授权码许可类型和隐式许可类型流程使用。客户端使用下列参数通知授权服务器期望的许可类型:
response_type
必需的。其值必须是

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

3.1.2. Redirection Endpoint 重定向端点

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

3.2. Token Endpoint 令牌端点

如用户授权微信登录后,第三方网站将授权码作为参数,以及其他必要的参数(如客户端ID、客户端密钥等)发送到微信开放平台的令牌端点进行令牌交换。令牌端点的URL类似于以下示例:
https://api.weixin.qq.com/sns/oauth2/access_token?appid=YOUR_APPID&secret=YOUR_APPSECRET&code=AUTHORIZATION_CODE&grant_type=authorization_code

在这个URL中,YOUR_APPID是第三方网站的客户端ID,YOUR_APPSECRET是客户端密钥,AUTHORIZATION_CODE是前面步骤中获取的授权码。这个url就是令牌端点。

3.3. Access Token Scope 访问令牌范围

授权端点和令牌端点允许客户端使用“scope”请求参数指定访问请求的范围。反过来,授权服务器使用“scope”响应参数通知客户端颁发的访问令牌的范围。
范围参数的值表示为以空格分隔,大小写敏感的字符串。 由授权服务器定义该字符串。如果该值包含多个空格分隔的字符串,他们的顺序并不重要且每个字符串为请求的范围添加一个额外的访问区域。
常见的示例scope值:

  • openid:用于身份验证和获取用户的唯一标识符。
  • profile:用于获取用户的基本资料信息,如姓名、头像等。
  • email:用于获取用户的电子邮件地址。
  • address:用于获取用户的联系地址信息。
  • phone:用于获取用户的电话号码。
  • offline_access:用于请求长期有效的访问令牌,以便在用户不再在线时也能访问资源。

4. Obtaining Authorization 获得授权

为了请求访问令牌,客户端从资源所有者获得授权。授权表现为授权许可的形式,客户端用它请求访问令牌。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)、(B)和(C)的直线因为通过用户代理而被分为两部分。
(A)客户端通过向授权端点引导资源所有者的用户代理开始流程。客户端包括它的客户端标识、请求范围、本地状态和重定向URI,一旦访问被许可(或拒绝)授权服务器将传送用户代理回到该URI。

(B)授权服务器验证资源拥有者的身份(通过用户代理),并确定资源所有者是否授予或拒绝客户端的访问请求。

(C)假设资源所有者许可访问,授权服务器使用之前(在请求时或客户端注册时)提供的重定向URI重定向用户代理回到客户端。重定向URI包括授权码和之前客户端提供的任何本地状态。

(D)客户端通过包含上一步中收到的授权码从授权服务器的令牌端点请求访问令牌。当发起请求时,客户端与授权服务器进行身份验证。客户端包含用于获得授权码的重定向URI来用于验证。

(E)授权服务器对客户端进行身份验证,验证授权代码,并确保接收的重定向URI与在步骤(C)中用于重定向客户端的URI相匹配。如果通过,授权服务器响应返回访问令牌与可选的刷新令牌。

4.1.1. Authorization Request 授权请求

客户端通过按附录B使用“application/x-www-form-urlencoded”格式向授权端点URI的查询部分添加下列参数构造请求URI:
response_type
    必需的。值必须被设置为“code”。
client_id
    必需的。如2.2节所述的客户端标识。
redirect_uri
    可选的。如3.1.2节所述。
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定向用户代理,或者通过经由用户代理至该URI的其他可行方法。

4.1.2. Authorization Response 授权响应

如果资源所有者许可访问请求,授权服务器颁发授权码,通过按附录B使用“application/x-www-form-urlencoded”格式向重定向URI的查询部分添加下列参数传递授权码至客户端:
code
    必需的。授权服务器生成的授权码。授权码必须在颁发后很快过期以减小泄露风险。推荐的最长的授权码生命周期是10分钟。客户端不能使用授权码超过一次。如果一个授权码被使用一次以上,授权服务器必须拒绝该请求并应该撤销(如可能)先前发出的基于该授权码的所有令牌。授权码与客户端标识和重定向URI绑定。
state
    必需的,若“state”参数在客户端授权请求中提交。从客户端接收的精确值。
例如,授权服务器通过发送以下HTTP响应重定向用户代理:

]HTTP/1.1 302 Found
Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
          &state=xyz
4.1.2.1. Error Response 错误响应

error
    必需的。下列ASCII[USASCII]错误代码之一:

错误码说明
invalid_request请求缺少必需的参数、包含无效的参数值、包含一个参数超过一次或其他不良格式。
unauthorized_client客户端未被授权使用此方法请求授权码。
access_denied资源所有者或授权服务器拒绝该请求。
unsupported_response_type授权服务器不支持使用此方法获得授权码。
invalid_scope请求的范围无效,未知的或格式不正确。
server_error授权服务器遇到意外情况导致其无法执行该请求。(此错误代码是必要的,因为500内部服务器错误HTTP状态代码不能由HTTP重定向返回给客户端)。
temporarily_unavailable授权服务器由于暂时超载或服务器维护目前无法处理请求。(此错误代码是必要的,因为503服务不可用HTTP状态代码不可以由HTTP重定向返回给客户端)。

error_description
    可选的。提供额外信息的人类可读的ASCII[USASCII]文本,用于协助客户端开发人员理解所发生的错误。

error_uri
    可选的。指向带有有关错误的信息的人类可读网页的URI,用于提供客户端开发人员关于该错误的额外信息。

state
    必需的,若“state”参数在客户端授权请求中提交。从客户端接收的精确值。
例如,授权服务器通过发送以下HTTP响应重定向用户代理:

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

4.1.3. Access Token Request 访问令牌请求

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

授权服务器必须:

o 对于机密的客户端或已发放客户端凭证(或其他身份验证要求)的任何客户端,要求客户端进行身份验证。
o 如果包含了客户端身份验证,则对客户端进行身份验证。
o 确保授权码是发给经过身份验证的机密客户端的,或者如果客户端是公开的,则确保授权码是发给请求中的"client_id"。
o 验证授权码的有效性。
o 确保如果初始授权请求中包含了"redirect_uri"参数,则"redirect_uri"参数也必须存在,并且如果存在,则确保其值相同。

4.1.4. Access Token Response 访问令牌响应

An example successful response:

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. Implicit Grant 隐式许可

隐式授权类型被用于获取访问令牌(它不支持发行刷新令牌),并对知道操作具体重定向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)客户端通过向授权端点引导资源所有者的用户代理开始流程。客户端包括它的客户端标识、请求范围、本地状态和重定向URI,一旦访问被许可(或拒绝)授权服务器将传送用户代理回到该URI。

(B)授权服务器验证资源拥有者的身份(通过用户代理),并确定资源所有者是否授予或拒绝客户端的访问请求。

(C)假设资源所有者许可访问,授权服务器使用之前(在请求时或客户端注册时)提供的重定向URI重定向用户代理回到客户端。重定向URI在URI片段中包含访问令牌。

(D)用户代理顺着重定向指示向Web托管的客户端资源发起请求(按RFC2616该请求不包含片段)。用户代理在本地保留片段信息。

(E)Web托管的客户端资源返回一个网页(通常是带有嵌入式脚本的HTML文档),该网页能够访问包含用户代理保留的片段的完整重定向URI并提取包含在片段中的访问令牌(和其他参数)。

(F)用户代理在本地执行Web托管的客户端资源提供的提取访问令牌的脚本。

(G)用户代理传送访问令牌给客户端。

参见1.3.2节和第9节了解使用隐式许可的背景。

参见10.3节和10.16节了解当使用隐式许可时的重要安全注意事项。

4.2.1. Authorization Request 授权请求

response_type
    必需的。值必须设置为“token”。

client_id
    必需的。如2.2节所述的客户端标识。

redirect_uri
    可选的。如3.1.2节所述。

scope
    可选的。如3.3节所述的访问请求的范围。

state
    推荐的。客户度用于维护请求和回调之间的状态的不透明的值。当重定向用户代理回到客户端时,授权服务器包含此值。该参数应该用于防止如10.12所述的跨站点请求伪造。

例如,客户端使用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

4.2.2. Access Token Response 访问令牌响应

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
4.2.2.1. Error Response 错误响应

响应参数略

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

HTTP/1.1 302 Found
Location: https://client.example.com/cb#error=access_denied&state=xyz

4.3. Resource Owner Password Credentials Grant 资源所有者密码凭据许可

资源所有者密码凭据许可类型适合于资源所有者与客户端具有信任关系的情况,如设备操作系统或高级特权应用。当启用这种许可类型时授权服务器应该特别关照且只有当其他流程都不可用时才可以。

这种许可类型适合于能够获得资源所有者凭据(用户名和密码,通常使用交互的形式)的客户端。通过转换已存储的凭据至访问令牌,它也用于迁移现存的使用如HTTP基本或摘要身份验证的直接身份验证方案的客户端至OAuth。

     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          v
          |    Resource Owner
         (A) Password Credentials
          |
          v
     +---------+                                  +---------------+
     |         |>--(B)---- Resource Owner ------->|               |
     |         |         Password Credentials     | Authorization |
     | Client  |                                  |     Server    |
     |         |<--(C)---- Access Token ---------<|               |
     |         |    (w/ Optional Refresh Token)   |               |
     +---------+                                  +---------------+

图5中的所示流程包含以下步骤:

(A)资源所有者提供给客户端它的用户名和密码。

(B)通过包含从资源所有者处接收到的凭据,客户端从授权服务器的令牌端点请求访问令牌。当发起请求时,客户端与授权服务器进行身份验证。

(C)授权服务器对客户端进行身份验证,验证资源所有者的凭证,如果有效,颁发访问令牌。

4.3.1. Authorization Request and Response 授权请求和响应

客户端获得资源所有者凭据所通过的方式超出了本规范的范围。一旦获得访问令牌,客户端必须丢弃凭据。

4.3.2. Access Token Request 访问令牌请求

grant_type
    必需的。值必须设置为“password”。

username
    必需的。资源所有者的用户名。

password
    必需的。资源所有者的密码。

scope
    可选的。如3.3节所述的访问请求的范围。

例如:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=password&username=johndoe&password=A3ddj3w

授权服务器必须遵守以下规定:

o 对于机密客户端或已颁发客户端凭据(或具有其他身份验证要求)的任何客户端,需要进行客户端身份验证。

o 如果包括了客户端身份验证,则需要对客户端进行认证。

o 使用现有的密码验证算法验证资源所有者的密码凭证。

由于此访问令牌请求使用了资源所有者的密码,授权服务器必须保护端点免受暴力攻击(例如使用速率限制或生成警报)。

4.3.3. Access Token Response 访问令牌响应

一个样例成功响应:

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.4. Client Credentials Grant 客户端凭据许可

当客户端请求访问它所控制的,或者事先与授权服务器协商(所采用的方法超出了本规范的范围)的其他资源所有者的受保护资源,客户端可以只使用它的客户端凭据(或者其他受支持的身份验证方法)请求访问令牌。

客户端凭据许可类型必须只能由机密客户端使用。

     +---------+                                  +---------------+
     |         |                                  |               |
     |         |>--(A)- Client Authentication --->| Authorization |
     | Client  |                                  |     Server    |
     |         |<--(B)---- Access Token ---------<|               |
     |         |                                  |               |
     +---------+                                  +---------------+

                     Figure 6: Client Credentials Flow

(A)客户端与授权服务器进行身份验证并向令牌端点请求访问令牌。
(B)授权服务器对客户端进行身份验证,如果有效,颁发访问令牌。

4.4.1. Authorization Request and Response 授权请求和响应

由于客户端身份验证被用作授权许可,所以不需要其他授权请求。

4.4.2. Access Token Request 访问令牌请求

grant_type
    必需的。值必须设置为“client_credentials”。

scope
    可选的。如3.3节所述的访问请求的范围。

例如:
POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials

4.4.3. 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,
	"example_parameter":"example_value"
}

4.5. Extension Grants 扩展许可

5. Issuing an Access Token 颁发访问令牌

5.1. Successful Response 成功的响应

授权服务器颁发访问令牌和可选的刷新令牌,通过向HTTP响应实体正文中添加下列参数并使用200(OK)状态码构造响应:
access_token
    必需的。授权服务器颁发的访问令牌。

token_type
    必需的。如7.1节所述的颁发的令牌的类型。值是大小写敏感的。

expires_in
    推荐的。以秒为单位的访问令牌生命周期。例如,值“3600”表示访问令牌将在从生成响应时的1小时后到期。如果省略,则授权服务器应该通过其他方式提供过期时间,或者记录默认值。

refresh_token
    可选的。刷新令牌,可以用于如第6节所述使用相同的授权许可获得新的访问令牌。

scope
    可选的,若与客户端请求的范围相同;否则,必需的。如3.3节所述的访问令牌的范围。

在任何包含令牌、凭据或其他敏感信息的响应中,授权服务器必须在其中包含值为“no-store”的HTTP“Cache-Control”响应头部域RFC2616,和值为“no-cache”的“Pragma”响应头部域RFC2616。例如:

     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"
     }

5.2. Error Response 错误响应

授权服务器使用HTTP 400(错误请求)状态码响应,在响应中包含下列参数:
error
    必需的。下列ASCII[USASCII]错误代码之一

错误类型描述
invalid_request请求缺少必需的参数、包含不支持的参数值(除了许可类型)、重复参数、包含多个凭据、采用超过一种客户端身份验证机制或其他不规范的格式。
invalid_client客户端身份验证失败(例如,未知的客户端,不包含客户端身份验证,或不支持的身份验证方法)。授权服务器可以返回HTTP 401(未授权)状态码来指出支持的HTTP身份验证方案。如果客户端试图通过“Authorization”请求标头域进行身份验证,授权服务器必须响应HTTP 401(未授权)状态码,并包含与客户端使用的身份验证方案匹配的“WWW-Authenticate”响应标头字段。
invalid_grant提供的授权许可(如授权码、资源所有者凭据)或刷新令牌无效、过期、吊销、与在授权请求使用的重定向URI不匹配或颁发给另一个客户端。
unauthorized_client进行身份验证的客户端没有被授权使用这种授权许可类型。
unsupported_grant_type授权许可类型不被授权服务器支持。
invalid_scope请求的范围无效、未知的、格式不正确或超出资源所有者许可的范围。

error_description
    可选的。提供额外信息的人类可读的ASCII[USASCII]文本,用于协助客户端开发人员理解所发生的错误。“error_description”参数的值不能包含集合%x20-21 /%x23-5B /%x5D-7E以外的字符。

error_uri
    可选的。指向带有有关错误的信息的人类可读网页的URI,用于提供客户端开发人员关于该错误的额外信息。“error_uri”参数值必须符合URI参考语法,因此不能包含集合%x21/%x23-5B /%x5D-7E以外的字符。

例如:

HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
	"error":"invalid_request"
}

6. Refreshing an Access Token 刷新访问令牌

参数:
    grant_type
必需的。值必须设置为“refresh_token”。

    refresh_token
必需的。颁发给客户端的刷新令牌。

scope
    可选的。如3.3节所述的访问请求的范围。请求的范围不能包含任何不是由资源所有者原始许可的范围,若省略,被视为与资源所有者原始许可的范围相同。

例如:

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

7. Accessing Protected Resources 访问受保护资源

7.1. Access Token Types 访问令牌类型

访问令牌的类型给客户端提供了成功使用该访问令牌(和类型指定的属性)发起受保护资源请求所需的信息 若客户端不理解令牌类型,则不能使用该访问令牌。

例如,RFC6750定义的“bearer”令牌类型简单的在请求中包含访问令牌字符串来使用:

 GET /resource/1 HTTP/1.1
 Host: example.com
 Authorization: Bearer mF_9.B5f-4.1JqM

而[OAuth-HTTP-MAC]定义的“mac”令牌类型通过与许可类型一起颁发用于对HTTP请求中某些部分签名的消息认证码(MAC)的密钥来使用。

 GET /resource/1 HTTP/1.1
 Host: example.com
 Authorization: MAC id="h480djs93hd8",
                    nonce="274312:dj83hs9s",
                    mac="kDZvddkndxvhGRXZhvuDjEWhGeE="

提供上面的例子仅作说明用途。建议开发人员在使用前查阅RFC6750和[OAuth-HTTP-MAC]规范。

每一种访问令牌类型的定义指定与“access_token”响应参数一起发送到客户端的额外属性。它还定义了HTTP验证方法当请求受保护资源时用于包含访问令牌。

7.2. Error Response 错误响应

如果资源访问请求失败,资源服务器应该通知客户端该错误。虽然规定这些错误响应超出了本规范的范围,但是本文档在11.4节建立了一张公共注册表,用作OAuth令牌身份验证方案之间分享的错误值。

主要为OAuth令牌身份验证设计的新身份验证方案应该定义向客户端提供错误状态码的机制,其中允许的错误值限于本规范建立的错误注册表中。

这些方案可以限制有效的错误代码是注册值的子集。如果错误代码使用命名参数返回,该参数名称应该是“error”。

其他能够被用于OAuth令牌身份验证的方案,但不是主要为此目的而设计的,可以帮顶他们的错误值到相同方式的注册表项。

新的认证方案也可以选择指定使用“error_description”和"error_uri"参数,用于以本文档中用法相同的方式的返回错误信息。

9. Native Applications 本机应用程序

本机应用程序是安装和执行在资源所有者使用的设备上的客户端(例如,桌面程序,本机移动应用)。本机应用程序需要关于安全、平台能力和整体最终用户体验的特别注意事项。

授权端点需要在客户端和资源所有者用户代理之间进行交互。本机应用程序可以调用外部的用户代理,或在应用程序中嵌入用户代理。例如:

外部用户代理-本机应用程序可以捕获来自授权服务器的响应。它可以使用带有操作系统已注册方案的重定向URI调用客户端作为处理程序,手动复制粘贴凭据,运行本地Web服务器,安装用户代理扩展,或者通过提供重定向URI来指定客户端控制下的服务器托管资源,反过来使响应对本机应用程序可用。

嵌入式用户代理-通过监视资源加载过程中发生的状态变化或者访问用户代理的cookies存储,本机应用程序直接与嵌入式用户代理通信,获得响应。

当在外部或嵌入式用户代理中选择时,开发者应该考虑如下:

外部用户代理可能会提高完成率,因为资源所有者可能已经有了与授权服务器的活动会话,避免了重新进行身份验证的需要。它提供了熟悉的最终用户体验和功能。资源所有者可能也依赖于用户代理特性或扩展帮助他进行身份验证(例如密码管理器、两步设备读取器)

嵌入式用户代理可能会提供更好的可用性,因为它避免了切换上下文和打开新窗口的需要。

嵌入式用户代理构成了安全挑战,因为资源所有者在一个未识别的窗口中进行身份验证,无法获得在大多数外部用户代理中的可视的保护。嵌入式用户代理教育用户信任未标识身份验证请求(使钓鱼攻击更易于实施)。

当在隐式许可类型和授权码许可类型中选择时,下列应该被考虑:

使用授权码许可类型的本机应用程序应该这么做而不需使用用户凭据,因为本机应用程序无力保持客户端凭据的机密性。

当使用隐式许可类型流程时,刷新令牌不会返回,这就要求一旦访问令牌过期就要重复授权过程。

10. Security Considerations 安全考量

10.1. Client Authentication 客户端身份验证

授权服务器为进行客户端身份验证的目的,为Web应用客户端创建客户端凭据。授权服务器被鼓励考虑比客户端密码更强的客户端身份验证手段。Web应用程序客户端必须确保客户端密码和其他客户端凭据的机密性。

授权不得向本地应用程序或基于用户代理的应用客户端颁发客户端密码或其他客户端凭据用于客户端验证目的。授权服务器可以颁发客户端密码或其他凭据给专门的设备上特定安装的本地应用程序客户端。

当客户端身份验证不可用时,授权服务器应该采用其他方式来验证客户端的身份-例如,通过要求客户端重定向URI的注册或者引入资源所有者来确认身份。当请求资源所有者授权时,有效的重定向URI是不足以验证客户端的身份,但可以用来防止在获得资源所有者授权后将凭据传递给假冒的客户端。

授权服务器必须考虑与未进行身份验证的客户端交互的安全实现并采取措施限制颁发给这些客户端的其他凭据(如刷新令牌)的潜在泄露。

10.2. Client Impersonation 客户端仿冒

如果被仿冒的客户端不能,或无法保持其客户端凭据保密。恶意客户端可能冒充其他客户端,并获得对受保护资源的访问权限。

授权服务器任何可能的时候必须验证客户端身份。如果授权服务器由于客户端的性质无法对客户端进行身份验证,授权服务器必须要求注册任何用于接收授权响应的重定向URI并且应该利用其他手段保护资源所有者防止这样的潜在仿冒客户端。例如,授权服务器可以引入资源所有者来帮助识别客户端和它的来源。

授权服务器应该实施显式的资源所有者身份验证并且提供给资源所有者有关客户端及其请求的授权范围和生命周期的信息。由资源所有者在当前客户端上下文中审查信息并授权或拒绝该请求。

授权服务器未对客户端进行身份验证(没有活动的资源所有者交互)或未依靠其他手段确保重复的请求来自于原始客户端而非冒充者时,不应该自动处理重复的授权请求。

10.3. Access Tokens 访问令牌

访问令牌凭据(以及任何机密的访问令牌属性)在传输和储存时必须保持机密性,并只与授权服务器、访问令牌生效的资源服务器和访问令牌被颁发的客户端共享。访问令牌凭据必须只能使用带有RFC2818定义的服务器身份验证的1.6节所述的TLS 传输。

当使用隐式授权许可类型时,访问令牌在URI片段中传输,这可能泄露访问令牌给未授权的一方。

授权服务器必须确保访问令牌不能被生成、修改或被未授权一方猜测而产生有效的访问令牌。

客户端应该为最小范围的需要请求访问令牌。授权服务器在选择如何兑现请求的范围时应该将客户端身份考虑在内,且可以颁发具有比请求的更少的权限的访问令牌。

本规范未给资源服务器提供任何方法来确保特定的客户端提交给它的访问令牌是授权服务器颁发给此客户端的。

10.4. Refresh Tokens 刷新令牌

授权服务器可以给Web应用客户端和本机应用程序客户端颁发刷新令牌。

刷新令牌在传输和储存时必须保持机密性,并只与授权服务器和刷新令牌被颁发的客户端共享。授权服务器必须维护刷新令牌和它被颁发给的客户端之间的绑定。刷新令牌必须只能使用带有RFC2818定义的服务器身份验证的1.6所述的TLS 传输。

授权服务器必须验证刷新令牌和客户端身份之间的绑定,无论客户端身份是否能被验证。当无法进行客户端身份验证时,授权服务器应该采取其他手段检测刷新令牌滥用。

例如,授权服务器可以使用刷新令牌轮转机制,随着每次访问令牌刷新响应,新的刷新令牌被颁发。以前的刷新令牌被作废但是由授权服务器保留。如果刷新令牌被泄露,随后同时被攻击者和合法客户端使用,他们中一人将提交被作废的刷新令牌,这将通知入侵给授权服务器。

授权服务器必须确保刷新令牌不能被生成、修改或被未授权一方猜测而产生有效的刷新令牌。

10.5. Authorization Codes 授权码

授权码的传输应该建立在安全通道上,客户端应该要求在它的重定向URI上使用TLS,若该URI指示了一个网络资源。 由于授权码由用户代理重定向传输,它们可能潜在地通过用户代理历史记录和HTTP参照标头被泄露。

授权码明以纯文本承载凭据使用,用于验证在授权服务器许可权限的资源所有者就是返回到客户端完成此过程的相同的资源所有者。因此,如果客户端依赖于授权码作为它自己的资源所有者身份验证,客户端重定向端点必须要求使用TLS。

授权码必须是短暂的且是单用户的。如果授权服务器观察到多次以授权码交换访问令牌的尝试,授权服务器应该试图吊销所有基于泄露的授权码而颁发的访问令牌。

如果客户端可以进行身份验证,授权服务器必须验证客户端身份,并确保授权码颁发给了同一个客户端。

10.6. Authorization Code Redirection URI Manipulation 授权码重定向URI伪造

当使用授权码许可类型请求授权时,客户端可以通过“redirect_uri”参数指定重定向URI。 如果攻击者能够伪造重定向URI的值,这可能导致授权服务器向攻击者控制的URI重定向带有授权码的资源所有者用户代理。

攻击者可以在合法客户端上创建一个帐户,并开始授权流程。当攻击者的用户代理被发送到授权服务器来许可访问权限时,攻击者抓取合法客户端提供的授权URI并用攻击者控制下的URI替换客户端的重定向URI。 攻击者然后欺骗受害者顺着仿冒的链接来对合法客户端授权访问权限。

一旦在授权服务器——受害者被唆使代表一个合法的被信任的客户端使用正常有效的请求——授权该请求时。受害者然后带着授权码重定向到受攻击者控制的端点。通过使用客户端提交的原始重定向URI向客户端发送授权码,攻击者完成授权流程。客户端用授权码交换访问令牌并与将它与攻击者的客户端账号关联,该账户现在能获得受害者授权的(通过客户端)对访问受保护资源的访问权限。

为了防止这种攻击,授权服务器必须确保用于获得授权码的重定向URI与当用授权码交换访问令牌时提供的重定向URI相同。授权服务器必须要求公共客户端,并且应该要求机密客户注册它们的重定向URI。如果在请求中提供一个重定向URI,授权服务器必须验证对注册的值。如果在请求中提供了重定向URI,授权服务器必须对比已注册的。

10.7. Resource Owner Password Credentials 资源所有者密码凭据

资源所有者密码凭据许可类型通常用于遗留或迁移原因。它降低了由客户端存储用户名和密码的整体风险,但并没有消除泄露高度特权的凭证给客户端的需求。

这种许可类型比其他许可类型承载了更高的风险,因为它保留了本协议寻求避免的密码反模式。客户端可能滥用密码或密码可能会无意中被泄露给攻击者(例如,通过客户端保存的日志文件或其他记录)。

此外,由于资源拥有者对授权过程没有控制权(在转手它的凭据给客户端后资源所有者的参与结束),客户端可以获得比资源所有者预期的具有更大范围的访问令牌。授权服务器应该考虑由这种许可类型颁发的访问令牌的范围和寿命。

授权服务器和客户端应该尽量减少这种许可类型的使用,并尽可能采用其他许可类型。

10.8. Request Confidentiality 请求机密性

访问令牌、刷新令牌、资源所有者密码和客户端凭据不能以明文传输。授权码不应该以明文传输。

“state”和“scope”参数不应该包含敏感的客户端或资源所有者的纯文本信息,因为它们可能在不安全的通道上被传输或被不安全地存储。

10.9. Ensuring Endpoint Authenticity 确保端点真实性

为了防止中间人攻击,授权服务器必须对任何被发送到授权和令牌端点的请求要求RFC2818中定义的具有服务器身份验证的TLS 的使用。客户端必须按RFC6125定义且按照它服务器身份进行身份验证的需求验证授权服务器的的TLS证书。

10.10. Credentials-Guessing Attacks 凭据猜测攻击

授权服务器必须防止攻击者猜测访问令牌、授权码、刷新令牌、资源所有者密码和客户端凭据。

攻击者猜测已生成令牌(和其它不打算被最终用户掌握的凭据)的概率必须小于或等于2 ^(-128),并且应该小于或等于2 ^(-160)。

授权服务器必须采用其他手段来保护打算给最终用户使用的凭据。

10.11. Phishing Attacks 钓鱼攻击

本协议或类似协议的广泛部署,可能导致最终用户变成习惯于被重定向到要求输入他们的密码的网站的做法。

如果最终用户在输入他们的凭据前不注意辨别这些网站的真伪,这将使攻击者利用这种做法窃取资源所有者的密码成为可能。

服务提供者应尝试教育最终用户有关钓鱼攻击构成的风险,并且应该为最终用户提供使确认它们的站点的真伪变得简单的机制。客户端开发者应该考虑他们如何与用户代理(例如,外部的和嵌入式的)交互的安全启示以及最终用户辨别授权服务器真伪的能力。

为了减小钓鱼攻击的风险,授权服务器必须要求在用于最终用户交互的每个端点上使用TLS。

10.12. Cross-Site Request Forgery 跨站请求伪造

跨站请求伪造(CSRF)是一种漏洞利用,攻击者致使受害的最终用户按恶意URI(例如以误导的链接、图片或重定向提供给用户代理)到达受信任的服务器(通常由存在有效的会话Cookie而建立)。

针对客户端的重定向URI的CSRF攻击允许攻击者注入自己的授权码或访问令牌,这将导致在客户端中使用与攻击者的受保护资源关联的访问令牌而非受害者的(例如,保存受害者的银行账户信息到攻击者控制的受保护资源)。

客户端必须为它的重定向URI实现CSRF保护。这通常通过要求向重定向URI端点发送的任何请求包含该请求对用户代理身份认证状态的绑定值(例如,用于对用户代理进行身份验证的会话Cookie的哈希值)来实现。客户端应该使用“state”请求参数在发起授权请求时向授权服务器传送该值。

一旦从最终用户获得授权,授权服务器重定向最终用户的用户代理带着要求的包含在“state”参数中的绑定值回到客户端。 通过该绑定值与用户代理的身份验证状态的匹配,绑定值使客户端能够验证请求的有效性。用于CSRF保护的绑定值必须包含不可猜测的值(如10.10节所述)且用户代理的身份验证状态(例如会话Cookie、HTML5本地存储)必须保存在只能被客户端和用户代理访问的地方(即通过同源策略保护)。

针对授权服务器的授权端点的CSRF攻击可能导致攻击者获得最终用户为恶意客户端的授权而不牵涉或警告最终用户。

授权服务器必须为它的授权端点实现CSRF保护并且确保在资源所有者未意识到且无显式同意时恶意客户端不能获得授权。

10.13. Clickjacking 点击劫持

在点击劫持攻击中,攻击者注册一个合法客户端然后构造一个恶意站点,在一个透明的覆盖在一组虚假按钮上面的嵌入框架中加载授权服务器的授权端点Web页面,这些按钮被精心构造恰好放置在授权页面上的重要按钮下方。当最终用户点击了一个误导的可见的按钮时,最终用户实际上点击了授权页面上一个不可见的按钮(例如“授权”按钮)。 这允许攻击者欺骗资源所有者许可它的客户端最终用户不知晓的访问权限。

为了防止这种形式的攻击,在请求最终用户授权时本机应用程序应该使用外部浏览器而非应用程序中嵌入的浏览器。 对于大多数较新的浏览器,避免嵌入框架可以由授权服务器使用(非标准的)“x-frame-options”标头实施。 该标头可以有两个值,“deny”和“sameorigin”,它将阻止任何框架,或按不同来源的站点分别构造框架。 对于较旧的浏览器,JavaScript框架破坏技术可以使用,但可能不会在所有的浏览器中生效。

10.14. Code Injection and Input Validation 代码注入和输入验证

代码注入攻击当程序使用的输入或其他外部变量未清洗而导致对程序逻辑的修改时发生。 这可能允许攻击者对应用程序的设备或它的数据的访问权限,导致服务拒绝或引入许多的恶意副作用。

授权服务器和客户端必须清洗(并在可能的情况下验证)收到的任何值–特别是,“state”和“redirect_uri”参数的值。

10.15. Open Redirectors 自由重定向器

授权服务器、授权端点和客户端重定向端点可能被不当配置,被作为自由重定向器。自由重定向器是一个使用参数自动地向参数值指定而无任何验证的地址重定向用户代理的端点。

自由重定向器可被用于钓鱼攻击,或者被攻击者通过使用熟悉的受信任的目标地址的URI授权部分使最终用户访问恶意站点。此外,如果授权服务器允许客户端只注册部分的重定向URI,攻击者可以使用客户端操作的自由重定向器构造重定向URI,这将跳过授权服务器验证但是发送授权码或访问令牌给攻击者控制下的端点。

10.16. Misuse of Access Token to Impersonate Resource Owner in Implicit Flow 在隐式流程中滥用访问令牌假冒资源所有者

对于使用隐式流程的公共客户端,本规范没有为客户端提供任何方法来决定访问令牌颁发给的是什么样的客户端。

资源所有者可能通过给攻击者的恶意客户端许可访问令牌自愿委托资源的访问权限。这可能是由于钓鱼或一些其他借口。攻击者也可能通过其他机制窃取令牌。 攻击者然后可能会尝试通过向合法公开客户端提供该访问令牌假冒资源拥有者。

在隐式流程(response_type=token)中,攻击者可以轻易转换来自授权服务器的响应中的令牌,用事先颁发给攻击者的令牌替换真实的访问令牌。

依赖于在返回通道中传递访问令牌识别客户端用户的与本机应用程序通信的服务器可能由攻击者创建能够注入随意的窃取的访问令牌的危险的程序被类似地危及。

任何做出只有资源所有者能够提交给它有效的为资源的访问令牌的假设的公共客户端都是易受这种类型的攻击的。

这种类型的攻击可能在合法的客户端上泄露有关资源所有者的信息给攻击者(恶意客户端)。这也将允许攻击者在合法客户端上用和资源所有者相同的权限执行操作,该资源所有者最初许可了访问令牌或授权码。

客户端对资源拥有者进行身份验证超出了本规范的范围。任何使用授权过程作为客户端对受委托的最终用户进行身份验证的形式的规范(例如,第三方登录服务)不能在没有其他的客户端能够判断访问令牌是否颁发是颁发给它使用的安全机制的情况下使用隐式流程(例如,限制访问令牌的受众)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值