代表性面试主题

系统设计面试:如何设计请求绑定的委托权限验证层?

系统设计困难
Offer.cc 编辑团队发布 更新

题干

请设计一个委托权限验证层:请求方代表用户或组织调用会花费资金、披露数据或修改生产状态的 HTTP API。系统如何挑战、签发、绑定、验证和撤销一次请求的委托权限?

题目与适用场景

请设计一个委托权限验证层:代理、工作负载或批处理任务代表用户或组织调用会花费资金、消耗计量资源、披露受监管数据或修改生产状态的 HTTP API。系统需要在执行受保护请求前证明请求方拥有有界权限。题目参考 IETF HTTPAPI 的 2026 年 Internet-Draft;该文档仍是 work in progress,不能视为最终 RFC,也不等于支付协议。

面试官考察点

  • 能否区分身份认证、委托授权、请求完整性和结算流程。
  • 能否设计 401 挑战、403 拒绝、nonce、过期时间和请求绑定。
  • 能否处理重放、跨租户混用、代理转发、密钥轮换和审计。
  • 能否在高风险动作前设置预算、策略和故障安全边界。

回答前需要澄清的问题

  1. 受保护动作是导出数据、写生产资源、调用下游,还是消费预算?
  2. 委托方、签发方、执行请求方和验证方分别由谁运营?
  3. 权限需要绑定 HTTP 方法、目标 URI、请求摘要,还是只绑定资源范围?
  4. 允许离线验证吗?nonce 状态可用性和时钟偏差如何处理?
  5. 失败时应拒绝请求、进入人工审批,还是降级为只读?

30 秒回答框架

把问题拆成四层:已有身份凭据证明“是谁”,委托证明说明“代表谁、能做什么、上限是多少”,请求绑定证明“只能用于哪一次请求”,验证策略决定“现在是否允许”。没有合格委托证明时返回 401 challenge;证明存在但权限不足时返回 403。证明应包含签发者、请求方、主体、过期时间、nonce、目标方法与 URI、摘要和预算边界。验证成功后再执行动作,所有失败路径都默认拒绝并保留审计。

分步骤深入解答

1. 定义角色与信任边界

主体是用户、组织或服务;委托请求方是代理、设备、任务或工作负载;签发方代表主体签发证明;验证方位于受保护资源或网关。OAuth Token Exchange 等系统可以负责取得证明,但验证层只负责挑战和呈现,不重复定义同意流程或账户绑定。

2. 设计挑战与响应

没有可接受证明时,验证方返回 401、WWW-Authenticate: DelegationCache-Control: no-store。证明语法有效但超过本地策略时返回 403。错误体可用 Problem Details,但不能让解释字段放宽挑战约束。

http
HTTP/1.1 401 Unauthorized
Cache-Control: no-store
WWW-Authenticate: Delegation realm="api.example",
  version=1, profile="budget", nonce="n-123", max-age=300

挑战中的 nonce、profile 和过期窗口应由验证方控制,避免跨请求复制。

3. 绑定到将要执行的请求

证明至少绑定 HTTP 方法、可信 origin、目标 URI、请求内容摘要和有效期。代理重写 Host 或路径时,验证方只使用受信任的网关配置重建 origin,不能采信未经验证的 X-Forwarded-*。方法大小写、查询参数顺序和百分号编码必须定义规范化规则。

json
{
  "principal": "org-42",
  "requester": "job-7",
  "method": "POST",
  "origin": "https://api.example",
  "target_hash": "sha-256:...",
  "nonce": "n-123",
  "expires": "2026-08-04T05:00:00Z",
  "limits": {"USD": 250}
}

4. 验证顺序与故障安全

先解析版本和格式,再验证签名、签发者信任、nonce 未重放、时间窗口、请求绑定和本地预算。任何依赖不可用、CBOR 非确定性、签名失败或 nonce 状态丢失都拒绝请求,不能在验证异常时自动放行。身份凭据与委托证明分层验证,不能把一个有效证明当成另一个 API key 的授权。

5. 防止重放和跨租户混用

nonce 存储需要短 TTL、原子消费和租户隔离;请求摘要与目标 origin 防止把同一证明复制到另一条 API。验证方应拒绝已使用 nonce,限制时钟偏差,并对预检与最终请求使用一致的绑定字段。高风险动作可以要求一次性证明和人工审批。

6. 预算与策略执行

预算只是一个权限 profile,不等于支付或结算。策略可以限制金额、服务单位、数据范围、环境和下游调用次数。扣减应在动作提交的同一事务边界内完成,或者使用可补偿的预留记录,避免并发请求共同超过上限。

7. 密钥、审计和可运维性

签发者发布可轮换的公钥与版本;验证方缓存但必须支持撤销和紧急密钥切换。审计记录主体、请求方、目标、策略结果、证明 ID 和拒绝原因,绝不记录完整 token、私钥或敏感数据。指标包括 401/403 比例、nonce 重放、验证延迟、策略拒绝、预算超限、密钥轮换失败和人工审批耗时。

高质量示范回答

我会把系统拆成身份、委托、请求绑定和策略四层。OAuth 或其他签发系统证明主体关系,委托证明携带主体、请求方、权限 profile、过期时间和预算;验证方再把证明绑定到即将执行的 HTTP 方法、可信 origin、目标 URI、请求摘要与 nonce。

没有证明时返回 401 和 WWW-Authenticate: Delegation,带 no-store;证明有效但权限不足返回 403。验证顺序是格式、签名和签发者信任、nonce 未使用、时间窗口、请求绑定、租户策略和预算。任何签名失败、依赖不可用或 nonce 状态丢失都默认拒绝。证明本身不定义支付,不替代 HTTP Message Signatures,也不等于 OAuth 的签发或用户同意流程。

预算扣减必须与动作提交处于同一事务或可补偿边界;nonce 要原子消费并隔离租户。公钥支持轮换和紧急撤销,日志只保留证明 ID、主体、目标和结果。验收关注重放、跨租户复制、代理改写、并发超支和密钥轮换,最终目标是在高影响动作发生前证明“谁代表谁、能对哪条请求做什么”。

常见错误

  • 把委托证明当成通用身份认证、OAuth 签发流程或支付协议。
  • 只签发一个长期 token,不绑定方法、URI、摘要、nonce 和过期时间。
  • 在签名验证依赖不可用时放行请求,造成故障不安全。
  • 忽略代理重写和不可信 X-Forwarded-* 导致的目标混淆。
  • 记录完整凭据或把预算扣减放在动作之后,留下重放和超支窗口。

追问及应对

为什么需要 401 和 403 两种响应?

401 表示缺少、无效或不完整的委托证明,客户端可能通过 challenge 获取新证明;403 表示证明被理解但权限、预算或本地策略不足,重试同一证明没有意义。

nonce 服务短暂不可用时怎么办?

默认拒绝高风险请求,并保留 no-store 的可诊断错误。只有经过明确风险评估的低风险只读动作才可采用受限降级,不能把缓存的旧 nonce 当作一次性状态。

如何兼容 OAuth?

OAuth Token Exchange 或 GNAP 可以负责取得委托材料;验证层仍独立检查 request-bound proof。身份 token 与委托 proof 分别验证,避免把委托范围误当作身份 token 的全部权限。

这是不是支付协议?

不是。预算 profile 可表达金额或服务单位上限,但结算、支付轨道和 HTTP 402 的语义在系统外部定义,验证层只决定受保护动作是否满足委托策略。

公开来源

同类题目

相关面试工具

用 Solve 整理系统设计回答

从澄清需求开始,展开规模、架构、组件选择和取舍。

查看工具