Oauth 2.0 的 Client Credentials Grant 授权模式

153 阅读4分钟

Oauth 2.0 支持客户端的多种授权模式来获取 Access Token,包含 Authorization Code Grant、Implicit Grant、Resource Owner Password Credentials Grant、Client Credentials Grant 等。

Client Credentials Grant 流程如图 1 所示。具体包含两个步骤:

  1. Client 通常通过其客户端凭证(client_id, client_secret)(或其他支持的认证方式),向授权服务器(Authorization Server)发起认证,并尝试从授权服务器开放的获取 Token 的接口,获取 Access Token。
  2. 授权服务器(Authorization Server)认证来自客户端的请求。如果认证通过,则签发 Access Token;如果认证失败,则返回 HTTP 400 (Bad Request) status code 和 error code。
 +---------+                                  +---------------+
 |         |                                  |               |
 |         |>--(A)- Client Authentication --->| Authorization |
 | Client  |                                  |     Server    |
 |         |<--(B)---- Access Token ---------<|               |
 |         |                                  |               |
 +---------+                                  +---------------+

图 1:Client Credentials Grant 流程(图片来自 The OAuth 2.0 Authorization Framework 规范)

Client Credentials Grant 仅仅用于被信任的客户端。Client Credentials Grant 主要适用于 无用户参与的场景,即 服务器到服务器(Machine/Server to Machine/Server)通信,通常用于后端服务 或 API 之间的访问。在这种模式下,客户端(Client)使用自己的 客户端 ID(Client ID)和客户端密钥(Client Secret) 直接向授权服务器(Authorization Server)申请访问令牌(Access Token),而 不涉及用户身份。

1 认证的请求

对于授权服务器(Authorization Server)可能支持客户端密码(Client Password) 和其他认证方法。下面以常见的客户端密码(Client Password)为例。

1.1 客户端密码认证方式

1.1.1 传递客户端密码

客户端密码(Client Password)主要体现在 client_id 和 client_secret 上。关于如何传递客户端密码,取决于具体的认证模式(Authentication scheme)。授权服务器(Authorization Server)支持 HTTP Basic 认证模式(client_secret_basic)和基于密码的其他 HTTP 认证模式(例如通过 HTTP 请求实体主体中使用 UTF-8 字符编码,并采用 "application/x-www-form-urlencoded" 格式。(client_secret_post))。

1.1.1.1 HTTP Basic 认证模式(client_secret_basic)
Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3
1.1.1.2 HTTP 请求实体主体传递客户端密码的认证模式(client_secret_post)

Form 表单中的数据,需在 HTTP 请求实体主体中使用 UTF-8 字符编码,并采用 "application/x-www-form-urlencoded" 格式。

 POST /token HTTP/1.1
 Host: server.example.com
 Content-Type: application/x-www-form-urlencoded

 grant_type=client_credentials&scope=read
 &client_id=your-client-id&client_secret=your-client-secret

1.1.2 传递其他参数

Client 发送请求时携带的参数需在 HTTP 请求实体主体中使用 UTF-8 字符编码,并采用 "application/x-www-form-urlencoded" 格式添加以下参数:

  • grant_type:必须为 client_credentials【必填】
  • scope:【可选】

1.1.3 请求示例

1.1.3.1 客户端密码认证方式下采用 HTTP Basic 认证模式的请求示例

客户端密码(Client Password)认证方式下采用 HTTP Basic 认证模式(client_secret_basic)的请求示例,如代码清单 1 所示。 代码清单 1:客户端密码(Client Password)认证方式下采用 HTTP Basic 认证模式(client_secret_basic)的请求示例 client-password-client-secret-basic-scheme-request-example.shell

 curl -X POST \
    -u your-client-id:your-client-secret \
    -d "grant_type=client_credentials" \
    -d "scope=read" \
    http://token-endpoint:port/oauth2/token
1.1.3.2 客户端密码认证方式下采用 HTTP 请求实体主体传递客户端密码的认证模式的请求示例

客户端密码(Client Password)认证方式下采用 HTTP 请求实体主体传递客户端密码的认证模式(client_secret_post)的请求示例,如代码清单 2 所示。

代码清单 2:客户端密码(Client Password)认证方式下采用 HTTP 请求实体主体传递客户端密码的认证模式(client_secret_post)的请求示例 client-password-client-secret-post-scheme-request-example.shell

curl -X POST "http://token-endpoint:port/oauth2/token" \
     -H "Content-Type: application/x-www-form-urlencoded" \
     -d "grant_type=client_credentials" \
     -d "client_id=your-client-id" \
     -d "client_secret=your-client-secret" \
     -d "scope=read"

2 认证的响应

如果认证的请求有效并且 Authorization Server 授权通过的化,Authorization Server 就会签发 Access Token。其 json 的响应如图 2 所示。

 {
   "access_token":"mock-access-token",
   "token_type":"Bearer",
   "expires_in":3600,
   "scope":"read"
 }

图 2 认证通过并授权成功的示例

如果认证或授权失败,Authorization Server 则会返回 error 的响应。例如图 3 就是表示客户端认证失败。error 的值可能是 invalid_request、invalid_client、invalid_grant、unauthorized_client、unsupported_grant_type、invalid_scope。对于这些 error code 的含义,我们可以参考 rfc6749 5.2节 的解释,这里不再赘述。

{
  "error": "invalid_client"
}

图 3 认证或并授权失败的示例