跳到主要内容

使用 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 标签页上记录 DomainClient IDClient 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_onlyuse_jwks:要求使用 Bearer 访问 Token,并使用 Auth0 发布的公钥在本地验证 JWT 签名。

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

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

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

请求头值和报告的源地址会因客户端及网络环境而异。由于路由阻止相关信息被代理,上游请求头不应包含 AuthorizationX-Access-TokenX-Id-TokenX-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 插件参考