JWT 身份验证
Custom 提供程序让数据墙DBW 自行验证 JWT Bearer 令牌。引擎校验令牌的签名、issuer、audience 和过期时间,从 roles 声明中提取用户角色。这是生产环境中推荐的身份验证方式。
身份验证流程
1. 用户在身份提供程序(Okta / Auth0 / Keycloak)完成登录
2. 客户端应用从身份提供程序获取 Access Token
3. 客户端将令牌放入 Authorization: Bearer <token> 头
4. 数据墙DBW 从 /.well-known/openid-configuration 获取签名密钥
5. 数据墙DBW 验证令牌:签名 → issuer → audience → 过期时间
6. 验证通过后从 roles 声明提取角色列表
7. 进入授权层进行权限评估从身份提供程序获取的配置值
配置 JWT 验证需要两个关键信息:
| 值 | 来源 | 作用 |
|---|---|---|
| Issuer URL | 身份提供程序的 OAuth 元数据地址 | 引擎验证令牌中的 iss 声明,并自动发现签名密钥 |
| Audience | 应用的 Client ID 或 API 标识符 | 引擎验证令牌中的 aud 声明 |
Okta
Issuer 格式:https://<your-domain>.okta.com
Audience 通常为应用的 Client ID。
Auth0
Issuer 格式:https://<your-tenant>.<region>.auth0.com/
Audience 通常为 API 的 Identifier(在 Applications → APIs 中配置)。
Keycloak
Issuer 格式:https://<host>/realms/<realm>
Audience 为应用的 Client ID。
配置数据墙DBW
# 设置提供程序
dab configure --runtime.host.authentication.provider Custom
# 设置 issuer
dab configure --runtime.host.authentication.jwt.issuer "https://your-tenant.auth0.com/"
# 设置 audience
dab configure --runtime.host.authentication.jwt.audience "https://api.example.com"生成的配置:
{
"runtime": {
"host": {
"authentication": {
"provider": "Custom",
"jwt": {
"issuer": "https://your-tenant.auth0.com/",
"audience": "https://api.example.com"
}
}
}
}
}roles 声明
数据墙DBW 固定从 JWT 的 roles 声明中提取角色,此声明名不可配置。如果你的身份提供程序使用了其他声明名(如 groups、permissions、realm_access.roles),需要配置提供程序将角色信息映射到 roles 声明中。
roles 声明可以是一个字符串或字符串数组。引擎将所有值视为用户拥有的角色列表。
客户端调用
客户端在调用 API 时携带令牌和角色选择头:
# 以 authenticated 角色调用(默认)
curl http://localhost:5000/api/Book \
-H "Authorization: Bearer eyJhbGciOi..."
# 以特定角色调用
curl http://localhost:5000/api/Book \
-H "Authorization: Bearer eyJhbGciOi..." \
-H "X-MS-API-ROLE: editor"- 不传
X-MS-API-ROLE时,按Authenticated系统角色评估。 - 传了
X-MS-API-ROLE但令牌的roles声明中不包含该角色时,返回 403。 - 令牌无效或过期时,返回 401。
令牌验证细节
引擎在验证令牌时检查以下内容:
| 检查项 | 失败结果 |
|---|---|
| 签名有效性(通过 issuer 的 JWKS 端点获取公钥) | 401 |
iss 声明是否与配置的 jwt.issuer 匹配 | 401 |
aud 声明是否包含配置的 jwt.audience | 401 |
exp(过期时间)是否已过 | 401 |
nbf(生效时间)是否尚未到达 | 401 |
验证通过后,引擎不会将令牌传递给数据库——令牌只在数据墙DBW 内使用。数据库只看到数据墙DBW 的连接身份,除非启用了 set-session-context。
权限配置
JWT 模式下可以区分不同角色:
{
"Book": {
"permissions": [
{ "role": "anonymous", "actions": ["read"] },
{ "role": "authenticated", "actions": ["read", "create"] },
{ "role": "editor", "actions": ["read", "create", "update"] },
{ "role": "admin", "actions": ["*"] }
]
}
}角色名区分大小写,必须与 JWT roles 声明中的值完全一致。
故障排查
| 问题 | 可能原因 | 检查方法 |
|---|---|---|
| 始终 401 | issuer 或 audience 不匹配 | 解码 JWT 检查 iss 和 aud,与配置对比 |
| 始终 401 | 签名密钥获取失败 | 确认 /.well-known/openid-configuration 可访问 |
| 始终 403 | roles 声明不存在或为空 | 解码 JWT 检查 roles,确认提供程序已配置输出 |
| 始终 403 | 角色名大小写不匹配 | 确认 JWT 中的角色名与 permissions 中完全一致 |
开发阶段建议先用 Simulator 模式验证权限规则正确,确认无误后再切换到 Custom 连接真实身份提供程序。
