多租户身份与租户识别策略:租户上下文传递、租户解析中间件、跨域身份映射

边界定义:本章聚焦多租户SaaS架构中的身份边界与租户识别域。认证(Authentication)确认用户身份,租户识别(Tenant Resolution)则决定用户在哪个租户范围内操作。两者构成IAM(身份与访问管理)前两层,任何一层被突破都会导致跨租户数据越权。信任边界从外部请求到达接入层开始,终止于下游服务读取租户上下文的点。

分层架构与核心职责

架构层组件职责
接入层负载均衡 / TLS 卸载识别目标域名,处理 SSL 终止,转发原始请求头
网关层反向代理 / API 网关认证令牌校验,提取租户标识并将其注入自定义请求头
中间件层租户解析中间件从 Host / Path / JWT Claims 中解析租户 Slug 或 ID
上下文层租户上下文管理器存储当前请求的租户信息,向下游业务服务透明传递
业务层核心微服务依赖上下文进行租户级数据路由和隔离策略执行

核心策略方案详解

1. 租户上下文传递

在请求链路中持续传递租户标识。常见模式:

  • 线程本地变量(ThreadLocal):适用于同步阻塞模型,需注意线程池复用导致上下文泄漏。
  • 请求上下文:GraphQL Context、gRPC Metadata、HTTP Header(X-Tenant-ID),显式传递,安全可控。
  • JWT Claims:在令牌中携带 tid、org_slug 等声明,实现无状态租户传递。
// JWT Payload 示例
{
  "sub": "user_uuid_12345",
  "tid": "acme-corp",
  "roles": ["admin", "billing_manager"]
}

2. 租户解析中间件

解析方式典型实现优劣
基于域名读取 Host 头,映射 tenantA.example.com强制隔离性强,但依赖 DNS 和泛域名证书
基于路径从 /{tenant_slug}/api/v1 提取第一段路径部署简单,适合全托管 SaaS;路径重写易出错
基于请求头自定义 Header X-Tenant-Id纯 RESTful,适合 B2B API 集成;客户端需配合
基于令牌声明从 Bearer JWT 的 aud / iss / tid 字段解析无状态,零配置改动;令牌过期需重新映射

3. 跨域身份映射

当租户使用外部身份提供商(IdP:Azure AD、Okta、自建 IdP)时,需将外部用户/组映射到内部租户和角色。核心模式:

  • JIT(Just-In-Time)预配:首次登录时自动创建用户和租户关联,用户组通过 IdP 属性映射。
  • SCIM 2.0 标准同步:从 IdP 同步用户与群组到 SaaS 系统,实时更新租户成员关系。
  • 外部 JWT 映射:信任外部令牌的 tid 声明,通过白名单或群体映射表建立互信。

风险提示:跨域映射一定要进行群体(Group)层级映射,避免直接映射个人账号,否则会极大增加租户数据泄露风险和运维复杂度。

数据流与控制流

控制流路径:客户端请求 → API 网关(认证) → 租户解析中间件 → 上下文注入 → 业务逻辑编排 → 数据层查询。

数据流约束:所有持久化查询必须携带租户上下文作为隐式过滤条件(WHERE tenant_id = ?),不允许上层自行拼接。

信任链路核心:TLS 终止 → 网关 JWT/OIDC 验证 → 租户声明提取并签名 → 服务间 mTLS 或 Token Exchange → 数据层查询过滤器。任何一环的信任失败都会导致租户边界失效。

选型权衡

维度域名解析路径解析Header/声明解析
DNS 配置成本高(泛域名、多证书)低低
证书管理复杂(SNI 证书)简单简单
API 客户端适配自动适配易适配需修改客户端
租户隔离速度快(连接级)慢(应用层重写)中(需解析 Header)
适用场景单租户规格,强隔离标准多租户 SaaSB2B API / 联邦认证

风险点与防范

  • 租户标识泄露:错误地将 X-Tenant-ID 暴露在客户端日志里。使用加密 JWT Claims 传递,避免明文 Header。
  • 线程池上下文污染:异步处理(如 Spring @Async)不继承父线程的 ThreadLocal。使用请求级上下文容器(如 ContextSnapshot)显式传递。
  • 跨域映射欺诈:恶意用户尝试伪装成其他租户的 IdP 组。校验外部令牌的 Issuer 和 Audience,静态配置信任锚点。
  • DNS 重新绑定攻击:基于域名的方案需配置严格的主机头白名单和 TLS 验证。

落地执行步骤

  1. 选定租户标识模式:使用 UUID(不可枚举)或 Slug(可读性高,如 acme-corp)。
  2. 标准化传递协议:统一使用请求头或 JWT Claims 传递租户 ID,确保语言无关。
  3. 开发/配置解析中间件:Kong 自定义插件 / Spring Cloud Gateway Filter / APISIX 租户路由插件。
  4. 强制校验机制:中间件不能解析出合法租户时直接返回 401/403,不允许降级为公共租户。
  5. 集成外部 IdP:配置 OIDC 发现端点和 SCIM 钩子,建立组映射规则。
  6. 自动化测试覆盖:编写跨租户访问测试用例,确保各组件正确传递上下文。
  7. 生产监控:对未携带租户上下文的请求进行告警,并在 Trace 中注入租户标签。

验收标准

  • 100% 的 API 请求在进入业务逻辑前携带了有效的租户上下文。
  • 不存在任何接口可以绕过租户上下文直接进行数据访问。
  • 跨域身份映射延迟 <100ms(基于缓存场景)。
  • 租户解析中间件在峰值 10000 QPS 下无泄漏、无长 GC。
  • 安全渗透测试中,跨租户越权攻击全部被拦截并告警。

生产建议:在 JWT 中同时颁发 tenant_id 和 tenant_slug。ID 用于内部关联,Slug 用于日志归因和故障排查,两者配合可以有效减缓标识变更迁移带来的问题。

多租户身份识别与上下文流转架构 客户端请求 API 网关 租户解析中间件 (域名/路径/JWT) JWT 令牌解析 租户上下文管理器 下游业务服务 数据隔离层 关键原则:租户上下文的注入必须在业务逻辑执行之前完成,且对下游完全透明。 任何绕过上下文直接查询数据的操作都视为安全事件