Skip to content

排查权限问题

权限问题(401 Unauthorized 和 403 Forbidden)是数据墙DBW 最常见的故障类型。本文档提供系统化的诊断方法,帮助你快速定位是认证配置问题还是授权规则问题。

第一步:区分 401 和 403

状态码含义故障方向
401 Unauthorized身份验证失败——引擎无法确认请求方的身份认证配置
403 Forbidden身份验证通过,但当前角色无权执行该操作权限配置

诊断行动: 首先确认你遇到的是 401 还是 403。两者的排查方向完全不同。

401 排查:认证失败

检查认证提供程序配置

bash
dab configure --show-effective-permissions
# 确认 provider 设置
json
{
  "runtime": {
    "host": {
      "authentication": {
        "provider": "Custom"
      }
    }
  }
}
Provider预期行为
Unauthenticated不验证令牌——不应该出现 401。如果出现,检查是否有反向代理或中间件干涉了认证头
Custom验证 JWT 令牌——需要有效的 Authorization: Bearer <token>
Simulator开发模式下不验证——不应该出现 401

JWT 令牌验证失败(Custom 模式)

引擎验证令牌时逐项检查以下内容,任一失败返回 401:

检查项配置字段诊断方法
签名有效jwt.issuer(用于发现 JWKS)确认 /.well-known/openid-configuration 可访问
iss 声明匹配jwt.issuer解码 JWT,对比 iss 与配置
aud 声明匹配jwt.audience解码 JWT,对比 aud 与配置
令牌未过期检查 exp 时间戳
令牌已生效检查 nbf 时间戳

诊断步骤:

  1. jwt.io 解码令牌,查看 issaudexpnbf
  2. dab-config.json 中的配置对比。
  3. 确认身份提供程序的 OpenID 配置端点可访问。
  4. 确认系统时间与身份提供程序时间同步(exp/nbf 依赖时钟)。

Unauthenticated 模式下的 401

Unauthenticated 模式下引擎不执行任何令牌验证,理论上不应返回 401。如果出现,可能原因:

  • 反向代理或 API 网关在请求到达数据墙DBW 之前拦截了请求并返回 401。
  • 负载均衡器层面的认证配置。
  • 数据墙DBW 前还有其他服务处理了认证。

诊断步骤: 直接从数据墙DBW 的内部网络地址调用 API,排除中间层干扰。

403 排查:权限拒绝

确认最终生效角色

引擎每次请求只在一个角色的上下文下评估。确认实际使用的角色:

请求特征最终角色
Authorization 头(Unauthenticated 模式)Anonymous
有有效令牌,无 X-MS-API-ROLEAuthenticated
有有效令牌 + X-MS-API-ROLE: <role><role>(需令牌中包含该角色)
有有效令牌 + X-MS-API-ROLE: <role> 但令牌中无此角色拒绝(403)

诊断步骤: 在请求中显式设置 X-MS-API-ROLE 头,确认你期望的角色是否被引擎接收。

运行有效权限查看

bash
dab configure --show-effective-permissions

输出示例:

text
Entity: Book
    Role: anonymous        | Actions: Read
    Role: authenticated    | Actions: Read (inherited from: anonymous)
    Unconfigured roles inherit from: anonymous

检查:

  • 目标实体是否存在你期望的角色权限块。
  • 角色是否通过继承获得权限。
  • 操作名称是否正确(read 不是 getcreate 不是 insert)。

常见 403 原因

原因表现解决
实体未配置该角色的权限该角色对实体无任何 permissions 条目添加权限或确保角色能通过继承获得
角色名大小写不匹配配置中是 Editor,令牌中是 editor统一大小写
操作名错误配置 "actions": ["read"] 但执行了 POST确认操作名与权限一致
Unauthenticated 模式 + 命名角色所有请求都是 anonymous,命名角色不生效切换认证模式或只为 anonymous 配置权限
通配符被误用存储过程的 * 只等于 execute,不等于 CRUD确认操作与实体类型匹配
策略中引用的声明不存在令牌中缺少 @claims.xxx 引用的声明配置身份提供程序输出缺失的声明

字段级 403

如果请求访问了被排除的字段:

  • REST $select 引用被排除字段 → 400 Bad Request(不是 403)。
  • GraphQL 查询被排除字段 → GraphQL 错误。
  • 不传 $select 时,被排除字段自动不出现在响应中。

诊断步骤: 检查该角色是否配置了 fields.exclude,确认请求中没有引用被排除的字段。

策略导致的 403

如果配置了数据库策略且策略引用了 JWT 声明:

json
{
  "policy": {
    "database": "@item.ownerId eq @claims.userId"
  }
}

当令牌中不存在 userId 声明时——引擎直接返回 403,不执行查询。

诊断步骤:

  1. 解码 JWT 令牌确认声明存在。
  2. 确认声明名拼写与策略中完全一致(区分大小写)。
  3. 身份提供程序可能需要在令牌中显式包含该声明。

角色继承的意外行为

角色继承可能带来两个意外:

意外原因
认为某个角色应该有权限但被 403该角色和继承链上的角色都没有权限块
认为某个角色不应该有权限但却能访问该角色从 anonymous / authenticated 继承了权限

诊断步骤: 运行 dab configure --show-effective-permissions,逐实体、逐角色查看继承结果,确认是否符合预期。

系统化排查流程

text
1. 确认 HTTP 状态码
   ├── 401 → 排查认证
   │     ├── 确认 provider 配置
   │     ├── 检查 JWT 令牌(Custom 模式)
   │     └── 排除中间层干扰(Unauthenticated 模式)
   └── 403 → 排查授权
         ├── 确认最终生效角色(X-MS-API-ROLE?默认?)
         ├── 运行 dab configure --show-effective-permissions
         ├── 检查实体 permissions 配置
         ├── 检查 fields.exclude
         ├── 检查 policy 中的 @claims 是否存在
         └── 确认角色继承是否符合预期

下一步

数据墙DBW 产品文档与开发指南。