跳到主要内容
版本:3.18.0

使用 Auth0 为 M2M 请求授权

Auth0 是一个可以向应用颁发访问 Token 的云身份平台。后台服务、计划任务、命令行工具和自动化程序可以使用这些 Token 调用 API,而无需最终用户登录。

OAuth 2.0 客户端凭证流程专为此类机器到机器(M2M)通信而设计。Apache APISIX 可以在代理请求前验证每个 Token 的签名、颁发者、受众和所授予的权限,从而保护目标 API。

本指南介绍如何为 APISIX 配置 Auth0 自定义 API 和 M2M 应用。该应用获得读取受保护消息的权限,并使用客户端凭证请求访问 Token。APISIX 使用 Auth0 的 JSON Web Key Set(JWKS)在本地验证 Token,并在将请求转发到示例上游之前移除身份认证数据。

前置条件​

配置 Auth0​

注册自定义 API 以定义 Token 受众和权限,然后配置可请求这些权限的 M2M 应用。

创建自定义 API​

登录 Auth0 控制台并创建 API:

  1. 选择 Applications → APIs → Create API。
  2. 输入 APISIX Protected API 作为 API 名称。
  3. 输入 https://apisix.example.com 作为标识符。
  4. 保持 Auth0 作为 JWT 配置文件,并保持 RS256 作为签名算法。
  5. 选择 Create。

API 标识符会成为为该 API 颁发的访问 Token 的受众。它用于标识 API,但不必解析为网络端点。

添加 API 权限​

在 API 的 Permissions 标签页中,创建 APISIX 路由所需的权限:

  1. 输入 read:messages 作为权限。
  2. 输入 Read protected messages 作为说明。
  3. 选择 Add。

配置 M2M 应用​

注册自定义 API 时,Auth0 会创建一个测试 M2M 应用。为本指南配置该应用:

  1. 选择 Applications → Applications。
  2. 选择 APISIX Protected API (Test Application)。
  3. 在 Settings 标签页上,将应用重命名为 APISIX M2M Client,然后选择 Save Changes。
  4. 选择 API Access。
  5. 在 APISIX Protected API 行中选择 Edit。
  6. 选择 Client Access,选中 read:messages,然后选择 Save。

向 Auth0 M2M 客户端授予受保护 API 的访问权限

在生产环境中,请为每个调用服务分别注册 M2M 应用,并且只授予该服务所需的权限。

保存 OAuth 配置​

在 M2M 应用的 Settings 标签页上记录 Domain、Client ID 和 Client Secret。将它们与 API 标识符一起保存到环境变量中,并替换示例值:

export AUTH0_DOMAIN=your-tenant.us.auth0.com
export AUTH0_M2M_CLIENT_ID=replace-with-your-m2m-client-id
export AUTH0_M2M_CLIENT_SECRET=replace-with-your-m2m-client-secret
export AUTH0_API_AUDIENCE=https://apisix.example.com
export AUTH0_DISCOVERY="https://${AUTH0_DOMAIN}/.well-known/openid-configuration"

请妥善保管客户端密钥。将生产凭证存储在 Secret 管理器中,并按照组织的凭证轮换策略进行轮换。

配置 APISIX​

配置一条路由,在将请求转发到公共 HTTP 请求与响应服务 httpbin.org 之前接受 Auth0 Bearer Token。/anything/m2m/* 端点会返回请求详情以供验证。

选择使用 Admin API 或 ADC 配置路由。

创建一条使用 Auth0 的 JWKS 在本地验证 Bearer Token 的路由:

curl "http://127.0.0.1:9180/apisix/admin/routes/auth0-m2m" -X PUT \
--data-binary @- <<EOF
{
"uri": "/anything/m2m/*",
"plugins": {
"openid-connect": {
"client_id": "$AUTH0_API_AUDIENCE",
"discovery": "$AUTH0_DISCOVERY",
"bearer_only": true,
"use_jwks": true,
"claim_validator": {
"audience": {
"required": true,
"match_with_client_id": true
}
},
"required_scopes": ["read:messages"],
"set_access_token_header": false,
"set_id_token_header": false,
"set_userinfo_header": false
},
"proxy-rewrite": {
"headers": {
"remove": ["Authorization"]
}
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org:80": 1
}
}
}
EOF

client_id 设置为 Auth0 API 标识符,以便 APISIX 将其与 Token 的受众进行比较。M2M 应用的客户端 ID 仅用于请求访问 Token。

❶ bearer_only 和 use_jwks:要求使用 Bearer 访问 Token,并使用 Auth0 发布的公钥在本地验证 JWT 签名。

❷ claim_validator.audience:要求 Token 的 aud 声明与配置为 client_id 的 Auth0 API 标识符匹配。

❸ required_scopes:要求访问 Token 包含授予 M2M 应用的权限。

❹ set_access_token_header、set_id_token_header 和 set_userinfo_header:设置为 false,防止 APISIX 将访问 Token、ID Token 和 Token 声明添加到上游请求头。

❺ proxy-rewrite.headers.remove:在 APISIX 代理请求前移除原始 Bearer Token。如果上游应用必须接收访问 Token 或其声明,请复查这些请求头设置。

验证 M2M 授权​

从 Auth0 为受保护的 API 请求访问 Token:

export AUTH0_ACCESS_TOKEN="$(
curl -sS "https://${AUTH0_DOMAIN}/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "client_id=${AUTH0_M2M_CLIENT_ID}" \
--data-urlencode "client_secret=${AUTH0_M2M_CLIENT_SECRET}" \
--data-urlencode "audience=${AUTH0_API_AUDIENCE}" \
--data-urlencode "grant_type=client_credentials" | \
jq -er '.access_token'
)"

将访问 Token 发送到受保护的路由:

curl -i "http://127.0.0.1:9080/anything/m2m/get" \
-H "Authorization: Bearer ${AUTH0_ACCESS_TOKEN}"

返回 HTTP/1.1 200 OK 表示 APISIX 已接受为受保护 API 颁发且包含所需权限的 Token。响应正文应包含类似以下内容的字段:

{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "localhost",
"User-Agent": "curl/8.7.1",
"X-Amzn-Trace-Id": "Root=1-...",
"X-Forwarded-Host": "localhost:9080"
},
"json": null,
"method": "GET",
"origin": "192.168.155.1, xxx.xxx.xxx.xxx",
"url": "http://localhost:9080/anything/m2m/get"
}

请求头值和报告的源地址会因客户端及网络环境而异。由于路由阻止相关信息被代理,上游请求头不应包含 Authorization、X-Access-Token、X-Id-Token 或 X-Userinfo。

发送不带 Token 的相同请求:

curl -i "http://127.0.0.1:9080/anything/m2m/get"

由于该路由要求 Bearer Token,APISIX 应返回 HTTP/1.1 401 Unauthorized。

后续步骤​

你已配置 APISIX,使用 Auth0 的访问 Token 和权限为 M2M 请求授权。如需配置基于浏览器的用户身份认证,请参阅使用 Auth0 配置 SSO。有关更多 Token 验证和授权选项,请参阅 openid-connect 插件参考。