JWT Claim 映射
JWT 认证通过 jwt_subject 字段把一个外部身份绑定到一把调用方 API Key。这适合固定的 Agent 集群,但不适合企业身份提供方为成百上千的人员声明部门、群组或应用的场景:为每个人注册一把 Key 等于重复维护 IdP 的目录,而且 IdP 侧的变更永远不会自动传播。
Claim 映射弥补了这一缺口。映射是一条规则:它匹配 JWT 中已验证的声明(如部门名称、群组成员身份),并把请求解析到一把既有的调用方 API Key。被该规则放行的所有身份都以这把 Key 的模型与工具访问权限、限流和预算运行,而每个请求的用 量仍然会归因到 Token 中的具体身份。
Claims 只用于选择运营者已创建的 Key。任何声明值都不会变成配置:Token 无法指定上游、无法扩大模型白名单、也无法创造预算。未命中任何映射的 Token 会被拒绝。
映射如何求值
对于每个携带 JWT Bearer 的请求,在完成 JWT 认证所述的完整信任提供方验证之后:
- 如果某把调用方 API Key 直接绑定了 Token 的 Subject(
jwt_subject+jwt_provider),请求以该 Key 的身份运行。直接绑定对其 Subject 具有最高权威——包括已禁用的 Key,其请求仍会被拒绝。映射永远不会覆盖直接绑定。 - 否则,
jwt_provider指向命中信任提供方的已启用映射会按priority顺序求值——数值小者在前,同值按name排序——第一条match条件全部成立的映射决定所用的 Key。 - 如果没有任何映射命中,请求会被拒绝并返回
jwt_identity_unmapped。不存在默认放行。
映射的 match 是一组条件,所有条件必须同时成立:
| 字段 | 说明 |
|---|---|
claim | 要检查的声明。点号用于遍历嵌套对象(例如 realm_access.roles)。缺失的声明永不匹配。 |
op | exact——声明必须是等于 values 之一的字符串。contains——声明必须是数组,且其字符串 元素中包含 values 之一(非字符串元素会被忽略)。类型与操作符不符的声明永不匹配。 |
values | 接受的值;任一匹配即条件成立。 |
映射指向的 Key 必须存在于同一环境中:Key 已被删除的映射会拒绝命中的 Token,而不是放行;且 jwt_provider 指向的信任提供方必须先完成 Token 验证,规则才会被考虑。
前提条件
以下工作流基于 JWT 认证的配置:一个已注册的 OIDC 信任提供方、一个模型,以及 curl 和 jq。你还需要一把调用方 API Key 作为共享的策略 Key——被放行身份继承的模型访问权限、限流和预算的载体。
导出基础 URL、管理员 Token、环境 ID 和策略 Key 的 ID:
export AISIX_CP="http://localhost:8080/api"
export AISIX_TOKEN="YOUR_ADMIN_TOKEN"
export ENV_ID="YOUR_ENVIRONMENT_ID"
export POLICY_KEY_ID="YOUR_API_KEY_ID"
创建 Claim 映射
把 department 声明等于 finance 的所有身份放行到策略 Key 下:
curl -sS -X POST "$AISIX_CP/environments/$ENV_ID/claim_mappings" \
-H "Authorization: Bearer $AISIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "finance-dept",
"jwt_provider": "corp-keycloak",
"priority": 100,
"match": [
{"claim": "department", "op": "exact", "values": ["finance"]}
],
"resolve": {"api_key_id": "'"$POLICY_KEY_ID"'"}
}' | jq
响应会回显创建的映射。当环境中部分网关运行的版本早于 Claim 映射特性时,响应还会携带 warnings 数组——这些网关会完全跳过该规则,持续拒绝本应被放行的身份,请先升级它们再依赖此规则。