写点什么

M2M 场景之客户端凭证模式|OIDC & OAuth2.0 认证协议最佳实践系列 【4】

作者:Authing
  • 2023-06-01
    北京
  • 本文字数:3864 字

    阅读完需:约 13 分钟

M2M场景之客户端凭证模式|OIDC & OAuth2.0 认证协议最佳实践系列 【4】


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

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 所需调用接口列表

  • 获取 Token


POST${host}/oidc/token
复制代码


  • 校验 Token


POST${host}/oidc/token/introspection 
复制代码


  • 吊销 Token


POST${host}/oidc/revocation 
复制代码

1.2.2 Run in Postman

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


https://app.getpostman.com/run-collection/24730905-5d29e488-719e-4ffe-af21-a7c18298d328?action=collection%2Ffork&collection-url=entityId%3D24730905-5d29e488-719e-4ffe-af21-a7c18298d328%26entityType%3Dcollection%26workspaceId%3D13ff793c-024c-459d-b1f6-87e91c4769ed#?env%5BAuthing%20OIDC%5D=W3sia2V5IjoiaG9zdCIsInZhbHVlIjoiaHR0cHM6Ly9kZWVwbGFuZy5hdXRoaW5nLmNuIiwiZW5hYmxlZCI6dHJ1ZSwidHlwZSI6ImRlZmF1bHQifSx7ImtleSI6ImNsaWVudF9pZCIsInZhbHVlIjoiNjM4MmNmNDg2ZTVhNjk0NDNhZjI5NzFiIiwiZW5hYmxlZCI6dHJ1ZSwidHlwZSI6ImRlZmF1bHQifSx7ImtleSI6ImNsaWVudF9zZWNyZXQiLCJ2YWx1ZSI6Ijc3NWMyM2NlMjkwYzkwZDQwNDUxNGU3MDgyMDkzZWIzIiwiZW5hYmxlZCI6dHJ1ZSwidHlwZSI6ImRlZmF1bHQifSx7ImtleSI6ImFjY2Vzc190b2tlbiIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZSwidHlwZSI6ImRlZmF1bHQifSx7ImtleSI6ImlkX3Rva2VuIiwidmFsdWUiOiIiLCJlbmFibGVkIjp0cnVlLCJ0eXBlIjoiZGVmYXVsdCJ9LHsia2V5IjoicmVmcmVzaF90b2tlbiIsInZhbHVlIjoiIiwiZW5hYmxlZCI6dHJ1ZSwidHlwZSI6ImRlZmF1bHQifV0=
复制代码

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 常用的授权模式我们已经介绍完毕。


以下是 OIDC & OAuth2.0 认证协议最佳实践系列文章目录,点击链接查看原文:


OIDC & OAuth2.0 协议及其授权模式详解|认证协议最佳实践系列【1】


OIDC & OAuth2.0 授权码模式接入 Authing | 认证协议最佳实践系列【2】


授权码 + PKCE 模式|OIDC & OAuth2.0 认证协议最佳实践系列【03】

用户头像

Authing

关注

还未添加个人签名 2022-01-24 加入

还未添加个人简介

评论

发布
暂无评论
M2M场景之客户端凭证模式|OIDC & OAuth2.0 认证协议最佳实践系列 【4】_OAuth 2.0_Authing_InfoQ写作社区