免费注册,打造高效身份管理
博客/开发者/M2M场景之客户端凭证模式|OIDC & OAuth2.0 认证协议最佳实践系列 【4】
M2M场景之客户端凭证模式|OIDC & OAuth2.0 认证协议最佳实践系列 【4】
Authing 官方2023.04.27阅读 1473

在前两篇文章中,我们介绍了 OIDC 授权码以及授权码增强的 PKCE 模式,本次我们将重点围绕 (Client Credentials) 模式进行讲解 ,Client Credentials 模式是 OIDC 授权模式之一,它是一种用于客户端(应用程序)以自己的名义向 OIDC 服务端获取访问令牌(access token)的认证授权模式,常用于保护 API 或物联网场景。

Authing 是国内唯一以开发者为中心的全场景身份云产品,提供 1000+ API 和所有主流语言 SDK,拥有数十万开发者的社区生态。

01.客户端凭证模式(Client Credentials)

Client Credentials 模式用于进行服务器对服务器间的授权(M2M 授权),期间没有用户的参与。你需要提前创建编程访问账号,并将 AK、SK 密钥对交给你的资源调用方,需要注意的是,各厂商对此实现有所不同,例如 Okta 和 Auth0 对于 Client Credentials 的实现是将 Client ID 和 Client Secret 交给调用方,Authing 则是在应用下创建编程访问账号后将 AK/SK 交给调用方,调用方使用起来并没有什么不同,Authing 的方式更加适合在一个应用下有多个调用方进行管理。

⚠️ Client Credentials 模式不支持 Refresh Token。

整体上,有以下流程:

1.资源调用方将他的凭证 AK、SK 以及需要请求的权限 scope 发送到 Authing 授权端点。

2.如果凭证正确,并且调用方具备资源权限,Authing 为其颁发 AccessToken。

3.调用方携带 access_token 请求资源服务器。

4.资源服务器验证 Token 通过后,返回相关资源。

流程图如下:

1.1 准备接入

1.1.1 在 Authing 创建应用及配置

老样子,需要先在 Authing 创建应用。

配置授权模式

创建编程访问账号 ,交给你 API 的调用方

1.1.2 在 Auhing 定义权限,并对 AK SK 账号进行授权

注:在用户认证时 scope 所对应的是用户信息,在 AK/SK 获取 Token 时,scope 应该对应的是被授权的 API 权限。

1.1.2.1 Scope 权限规范

Authing 的 scope 权限项目以空格分隔,每一项的格式是

资源:资源标识符:资源操作

资源:资源标识符:资源操作。

以下是 Authing 支持的所有 scope 格式:

1、含义为编号为 1 的书籍资源的读取权限

book:1:read

2、含义为所有书籍资源的读取权限

book:*:read

3、含义为所有书籍资源的读取权限

book:read

4、含义为所有书籍资源的所有操作权限

book:*:*

5、含义为所有书籍资源的所有操作权限

book:*

6、含义为所有书籍资源的所有操作权限

book:

7、含义为所有资源的所有操作权限

*:*:*

8、含义为所有资源的所有操作权限

*:*

9、含义为所有资源的所有操作权限

*

1.1.2.2 在 Authing 权限管理中定义相关资源

我们定义下 book 资源:

1.1.2.3 对编程访问账号进行授权

我们在这里给刚才创建的编程访问账号调用方 A 进行授权,允许调用方 A 以 GET 请求访问 /book API ,并且只能获取 ID 为 20150 的这条订单

1.2 接入测试

1.2.1 所需调用接口列表

POST${host}/oidc/token 获取 Token
POST${host}/oidc/token/introspection 校验 Token
POST${host}/oidc/revocation 吊销 Token

1.2.2 Run in Postman

以下要介绍的接口可以通过我们的在线 postman collection 自行 fork 体验

1.2.3 获取 Token

POST${host}/oidc/token

用户在 Authing 侧完成登录操作后,Authing 会将生成的 code 作为参数回调到 redirect_uri 地址,此时通过 code 换 token 接口即可拿到对应的访问令牌 access_token

请求示例:

curl --location 'https://{host}/oidc/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id={AccessKey}' \
--data-urlencode 'client_secret={SecretKey}' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=book:20150:GET book:20150:POST' 

响应示例(成功):

{
"access_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Il9xcEhRQXFvbXd0Z3BKX2xZVHNtN2FMVEU3YUtJb0tQeFN5by1faDdGUVkifQ.eyJhenAiOiI2M2Y0ODA5OTlkNGY0MDRiZTViNDQ0NGEiLCJhdWQiOiI2M2Y0ODI1ZDhhNWRmNjYyNTU4YjI4MTQiLCJzY29wZSI6ImJvb2s6MjAxNTA6R0VUIiwiaWF0IjoxNjgxNzExNDU2LCJleHAiOjE2ODE3MTIwNTYsImp0aSI6IlBiSks5djNFTS1rS1o3bms4VmdBRms3eVVPRzJES2NwYUQ2M2gxaThmVlkiLCJpc3MiOiJodHRwczovL29pZGMtY2xpZW50LWNyZWRlbnRpYWxzLmF1dGhpbmcuY24vb2lkYyJ9.qPcJU84C9Ztjm5dk-im8ntatPaB5P8j3ZPdW1eoi-V5po8k32jexUemSEHInEfqdxcnY7OyR1pph6JVjehmoCAX6gqA_3fv20hUjnWQNqcZegAiNea4jQbLKlMsYnTQhhJWmzhs64LwCJD1RqQy0VtoL2ZVVfAEpySHWL6TwWVz0AkvQpZbzkF6FRCa03rli_jc1BNtpGUhvNdtGs6xJMMLJZ31dptrLlSSWSQ71t05fqBfEiToN6-JkwKXJedpHBvFWt_-XncQbksdQQc6krTcgaWkrIbv6LblTrtAifXLfOsANweOAG8QoKLh55vSMMBXdzdw-IzXeCDuwQT5P2w",
"token_type":"Bearer",
"expires_in":600,
"scope":"book:20150:GET",
"rejected_scope":"book:20150:POST"

这里 scope 是该变成访问账号所允许访问资源,rejected_scope 则是我们申请但是被拒绝的权限,我们刚才给调用方 A 只分配了 book:20150:GET 的权限,所以在我们同时请求 book:20150:GET 和 book:20150:POST 两个权限时,book:20150:POST 权限则会被拒绝,调用方获取到 access_token 后则可携带此 token 调用受保护的API。

响应示例(失败):

{
"error""server_error",
"error_description""编程访问账号不存在!"

1.2.4 校验 Token

POST${host}/oidc/token/introspection

API 服务器收到接口调用请求后,可以调用此接口来校验 access_token 的有效性以及是否有权限调用对应的API。

此端点接受 access_token、id_token、refresh_token ,并返回一个布尔值,指示它是否处于活动状态。如果令牌处于活动状态,还将返回有关令牌的其他数据。如果 token 无效、过期或被吊销,则认为它处于非活动状态。

access_token 可以使用 RS256 签名算法或 HS256 签名算法进行签名。下面是这两种签名算法的区别:

RS256是使用RSA算法的一种数字签名算法,它使用公钥/私钥对来加密和验证信息。RS256 签名生成的令牌比 HS256 签名生成的令牌更加安全,因为使用RSA密钥对进行签名可以提供更高的保护级别。使用RS256签名算法的令牌可以使用公钥进行验证,公钥可以通过 JWK 端点获取。

HS256是使用对称密钥的一种数字签名算法。它使用同一个密钥进行签名和验证。HS256 签名算法在性能方面比 RS256 签名算法更快,因为它使用的是对称密钥,而不是使用 RSA 公钥/私钥对来签名和验证。使用 HS256签名算法的令牌可以通过 shared secret (应用密钥)进行验证。

在实际应用中,RS256 算法更加安全,但同时也更加消耗资源,如果系统需要高性能,可以选择 HS256 签名算法。在线校验

请求参数

请求示例:

curl --location --request POST 'https://{host}/oidc/token/introspection' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id={应用ID}' \
--data-urlencode 'client_secret={应用密钥}' \
--data-urlencode 'token={ token }' \
--data-urlencode 'token_type_hint=access_token' 

校验 access_token 响应示例(校验通过):

{
"active"true,
"aud""63f4825d8a5df662558b2814",
"client_id""63f480999d4f404be5b4444a",
"exp": 1681713127,
"iat": 1681712527,
"iss""https://oidc-client-credentials.authing.cn/oidc",
"jti""EpveFqLsgskNIre8fK-h0AOK6oBIfZH6erT5iSrRKmd",
"scope""book:20150:GET",
"token_type""Bearer"

校验 access_token 响应示例(校验未通过):

{
"active"false

1.2.5 撤回 Token

POST${host}/oidc/token/revocation

API 服务可通过此接口撤销调用方的 access_token 。

请求参数

请求示例:

curl --location --request POST 'https://{host}/oidc/token/revocation' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id={应用ID}' \
--data-urlencode 'client_secret={应用密钥}' \
--data-urlencode 'token= {token}' \
--data-urlencode 'token_type_hint=access_token' 

响应示例(成功):

HTTP 200 OK

响应示例(失败):

{
"error""xxxx","error_description""xxxx"

02.本章总结

本章我们介绍了使用 Client Credentials 模式来保护 API ,至此 OIDC 常用的授权模式我们已经介绍完毕。

【Authing 是国内唯一以开发者为中心的全场景身份云产品,提供 1000+ API 和所有主流语言 SDK,拥有数十万开发者的社区生态。识别下方二维码,进入 Authing 开发者论坛或社群】

Authing 是国内唯一以开发者为中心的全场景身份云产品,为企业和开发者提供高安全、高性能、高生产力的用户认证和访问管理服务。

Authing 目前已经服务包括可口可乐、招商银行、三星集团、复星集团、万科集团、海底捞、元气森林在内的 40000+ 企业和开发者。

 
 

文章作者

avatar

Authing 官方

0

文章总数

authing blog rqcode
关注 Authing 公众号
随时随地发现更多内容
authing blog rqcode
添加 Authing 小助手
加入 Authing 开发者大家庭
身份顾问在线解答
当前在线
如何打造完整的身份体系?
立即沟通
authing
添加企业微信,领取行业资料
authing
authing
下载 Authing 令牌,体验快速登录认证!
免费使用
在线咨询
电话咨询