百积木文档
开发指南平台应用、模块与 Bundle 开发模块开发

Runtime 用户委托

在外部模块后端通过 ServiceReference 调用下游服务时,安全传递当前已验证用户,并由 Runtime 按服务跳点轮换短期委托。

ServiceReference token 证明来源服务可以调用目标服务及方法,但它不代表最终用户。目标方法还需要当前 用户时,Runtime 使用短期 Actor assertion 把已经建立的用户身份委托给外部模块后端。

外部服务不签名、不解析 assertion,也不从业务参数构造用户身份。它只在当前同步请求内接收并转发一个 不透明 Header:

X-Runtime-Actor-Assertion: <opaque-short-lived-assertion>

Actor assertion 不能替代 ServiceReference token

每次服务引用调用仍必须发送 Authorization: Bearer {reference.token}。Bearer token 决定来源服务能否调用 目标服务及方法;Actor assertion 只表示本次调用代表哪个已验证用户。缺少任一项都不能用另一项补足。

单跳调用

当 Runtime 把一个已建立用户身份的请求交给模块 A 外部后端时,会注入 Actor Header。模块 A 调用绑定的 模块 B 时,在每个 HTTP 请求上同时发送引用 token 和自己收到的 assertion:

POST {reference.url}/listManagedShops
Authorization: Bearer {reference.token}
X-Runtime-Actor-Assertion: {currentRequest.actorAssertion}
Content-Type: application/json

同一模块 A 可以在同一个短时同步请求中,把同一个 assertion 用于多个已绑定的 ServiceReference 调用。 新的入站业务请求必须使用 Runtime 新注入的值;服务不能建立跨请求 assertion 缓存。

链式调用与按跳轮换

服务 B 收到请求后如果还要调用模块 C,不负责替用户签名。Runtime 在验证 A 的 ServiceReference token 和 Actor assertion 后、把调用交给 B 外部后端之前,会为 B 轮换一个来源绑定为 B 的下一跳 assertion:

用户请求
  -> Runtime 为 A 注入 assertion-A
  -> A 使用 ServiceReference(A→B) + assertion-A 调用 Runtime
  -> Runtime 验证两项凭据,为 B 注入 assertion-B
  -> B 使用 ServiceReference(B→C) + assertion-B 调用 Runtime
  -> Runtime 验证两项凭据,为 C 注入 assertion-C

因此每个外部服务只有两个动作:读取本次入站请求中的 X-Runtime-Actor-Assertion,并在本次请求产生的 ServiceReference 调用中原样发送它。跨到新的目标服务时由 Runtime 自动轮换,A、B、C 都不持有签名密钥。

请求生命周期规则

  • Header 必须恰好有一个非空值;多个值、合并值或非法 Header 必须拒绝。
  • assertion 只保存在当前请求的内存上下文中,不进入数据库、缓存、消息队列、任务参数或事件载荷。
  • 不在访问日志、错误、指标、Trace、崩溃报告或调试响应中输出 assertion。
  • 不解析 assertion 格式、claims、过期时间或签名算法;这些是 Runtime 内部协议。
  • 业务重试只有在原请求仍在执行、当前 assertion 仍由 Runtime 接受且目标方法允许重试时才能继续使用。
  • 延迟任务、定时任务、异步消费者和请求结束后的补偿不能复用 assertion;它们必须使用自己的服务身份, 或从新的已认证用户入口重新建立委托。

缺失用户的处理

Actor Header 不保证一定存在。匿名入口、服务级后台任务或没有建立用户身份的调用不会虚构用户。目标方法 要求 userId 时,Runtime 必须在网络调用前失败关闭;外部服务不能回退到安装用户、生命周期 Hook 的 userId、环境默认用户、固定管理员或业务请求体中的同名字段。

只需要服务或工作区身份的方法不应为了统一字段而虚构 Actor。调用方也不能把 Actor Header 当作普通公开 Endpoint 的鉴权方式;它只对通过 ExternalServiceReference.url 返回 Runtime 的服务引用调用有效。

与生命周期和方法定义的关系

  • Actor assertion 不属于 ExternalServiceReference 的持久字段,不会通过生命周期 Hook 交付。
  • 生命周期 Hook 中的操作 userId 只描述执行该配置操作的用户,不能保存用于后续业务调用。
  • 模块 methodBody 不声明、映射或生成 X-Runtime-Actor-Assertion;该 Header 只由 Runtime 注入。
  • 外部后端可以在自己的 HTTP 入口把 assertion 包装成不实现 Debug/序列化的请求级类型,降低误记录风险。

完整的引用生成与 Bearer 调用方式见 ServiceReference 声明、绑定与运行时交付模块服务间调用协议

本页内容