4、租户标识解析:域名解析、请求头解析、JWT解析、路径参数解析
在多租户 SaaS 架构中,网关或应用层接收到请求后,首要任务是从请求中提取租户标识(Tenant ID)。租户标识的解析方式直接决定了鉴权拦截链路的入口设计。常见的解析策略包括:域名解析、请求头解析、JWT 解析和路径参数解析。每种方式在隔离性、易用性和安全性上各有侧重。
设计原则:租户标识解析应发生在请求进入业务逻辑之前,通常在 API 网关或中间件层完成。解析后的租户 ID 应注入请求上下文(如 Request Context),供后续鉴权、数据隔离和路由使用。
4.1 四种解析方式对比
| 解析方式 | 识别载体 | 隔离级别 | 部署复杂度 | 典型场景 |
|---|---|---|---|---|
| 域名解析 | Host / SNI | 高(物理/逻辑隔离) | 中(需 DNS 配置) | 大型企业租户、独立域名客户 |
| 请求头解析 | X-Tenant-ID / Custom Header | 中(依赖客户端规范) | 低(网关配置即可) | API 网关、微服务间调用 |
| JWT 解析 | JWT Payload (claims) | 高(自带签名防篡改) | 低(认证服务签发) | 单点登录、移动端、前后端分离 |
| 路径参数解析 | URL Path (/api/{tenant_id}/...) | 低(易泄露、难迁移) | 低(路由规则简单) | 早期 SaaS、内部管理工具 |
4.2 域名解析(Host-based Resolution)
客户端通过不同的域名访问 SaaS 服务,网关根据 HTTP Host 头或 TLS SNI 提取租户标识。例如:tenant-a.example.com 和 tenant-b.example.com 分别对应不同的租户。
- 优势:租户隔离性最强,支持独立 SSL 证书,便于租户自定义域名。
- 劣势:需要 DNS 管理和泛域名证书支持;租户数量大时域名管理成本上升。
- 实现要点:网关维护域名到租户 ID 的映射表(可缓存),解析失败时返回 400/404。
网关伪代码示例:
// 基于 Host 头解析租户
String host = request.getHeader("Host");
String tenantId = tenantDomainMap.get(host);
if (tenantId == null) {
throw new TenantNotFoundException("Unknown domain: " + host);
}
context.setTenantId(tenantId);
4.3 请求头解析(Header-based Resolution)
客户端在 HTTP 请求中携带自定义头部,如 X-Tenant-ID: tenant_123。网关或中间件直接读取该头部值作为租户标识。
- 优势:实现简单,不依赖 DNS,适合微服务间内部调用。
- 劣势:依赖客户端正确传递头部,存在被伪造的风险(需结合签名或内部网络隔离)。
- 安全增强:在网关层对头部进行校验或剥离外部请求中的敏感头部。
安全警告:切勿直接信任来自客户端的 X-Tenant-ID 头部。生产环境中应结合 JWT 签名或内部服务网格 mTLS 验证请求来源合法性。
4.4 JWT 解析(JWT-based Resolution)
租户标识嵌入在 JWT 的 Payload 中,通常放在 tenant_id 或 org_id 字段。网关验证 JWT 签名后,从 claims 中提取租户 ID。
- 优势:防篡改(HMAC/RSA 签名),可同时携带用户角色、权限等附加信息,适合分布式认证。
- 劣势:JWT 体积较大,解析有轻微性能开销;需维护密钥管理。
- 实现要点:网关需缓存公钥或对称密钥,避免每次请求都远程验证。
JWT Payload 示例:
{
"sub": "user_456",
"tenant_id": "tenant_abc",
"role": "admin",
"exp": 1718000000
}
4.5 路径参数解析(Path-based Resolution)
租户 ID 作为 URL 路径的一部分,例如:/api/v1/tenant_abc/orders。网关通过路由模板匹配提取路径中的租户参数。
- 优势:路由规则直观,适合快速原型或内部工具。
- 劣势:租户 ID 暴露在 URL 中,容易在日志、浏览器历史中泄露;路径变更影响所有租户。
- 适用场景:管理后台、非面向终端用户的内部服务。
最佳实践:尽量避免在公网 API 中使用路径参数传递租户 ID。如果必须使用,建议结合 HTTPS 和短时效 Token 降低泄露风险。
4.6 租户标识解析链路架构
下图展示了请求从客户端到达网关后,经过四种解析策略提取租户 ID,并注入到下游服务的完整链路。
4.7 组合策略与最佳实践
在实际生产环境中,往往不是单一策略,而是组合使用。例如:外部请求通过域名解析识别租户,内部微服务间通过 JWT 传递租户 ID,同时网关在转发时自动添加 X-Tenant-ID 头部供下游使用。
推荐组合策略:
- 外部入口:域名解析 + HTTPS(强隔离)
- 认证阶段:JWT 解析(防篡改,携带租户与用户信息)
- 内部转发:请求头解析(X-Tenant-ID,轻量高效)
- 兜底/兼容:路径参数解析(仅限管理后台或内部工具)
下表总结了四种解析方式在关键维度上的差异,帮助架构师根据业务场景做出选择:
| 维度 | 域名解析 | 请求头解析 | JWT 解析 | 路径参数解析 |
|---|---|---|---|---|
| 防篡改能力 | 中(依赖 DNS 安全) | 低(需额外签名) | 高(签名验证) | 低(明文暴露) |
| 性能开销 | 低(缓存映射) | 极低(读取头部) | 中(签名验证) | 极低(路由匹配) |
| 租户迁移成本 | 高(需变更 DNS) | 低(客户端更新头部) | 低(重新签发 Token) | 高(URL 变更) |
| 日志泄露风险 | 低(域名在日志中常见) | 中(需脱敏头部) | 低(Payload 可加密) | 高(URL 明文记录) |
关键提醒:无论采用哪种解析方式,租户 ID 提取后必须进行合法性校验(如格式验证、白名单检查),防止恶意请求通过伪造租户 ID 越权访问其他租户数据。