2. 鉴权与拦截链路概述:鉴权、授权、认证三者的关系,拦截链路在SaaS中的位置与作用
2.1 核心概念辨析:认证、授权、鉴权
在构建多租户SaaS鉴权拦截链路之前,必须厘清三个极易混淆的核心概念。它们是整个安全体系的基石,任何组件选型失误都源于对这三者关系的理解偏差。
| 概念 | 英文 | 核心问题 | 典型输出 | SaaS场景示例 |
|---|---|---|---|---|
| 认证 | Authentication | 你是谁? | 身份凭证(Token、Session ID) | 用户输入邮箱+密码登录,系统验证密码哈希后签发JWT |
| 授权 | Authorization | 你能做什么? | 权限策略(RBAC角色、ABAC属性规则) | 租户管理员为“销售员”角色分配“查看客户列表”权限 |
| 鉴权 | Authentication & Authorization | 你声称的身份是否有效?你是否有权执行此操作? | 允许/拒绝决策 | 拦截器校验JWT签名,并检查当前用户是否拥有“删除订单”权限 |
关键认知:在工程实践中,“鉴权”常作为认证+授权的统称。但在架构设计中,必须将认证与授权拆分为两个独立的拦截阶段,否则会导致租户隔离漏洞。
2.2 三者的逻辑关系与执行顺序
认证是授权的前提,鉴权是认证与授权的执行过程。在SaaS请求链路中,它们严格按以下顺序执行:
- 凭证提取:从请求头(Authorization Header)、Cookie或Query参数中提取Token。
- 认证校验:验证Token的签名、有效期、颁发者(Issuer)。若失败,直接返回401 Unauthorized。
- 身份解析:从Token中解析出用户ID、租户ID(Tenant ID)、角色列表等声明(Claims)。
- 授权决策:根据解析出的身份信息,查询权限策略,判断是否允许执行当前操作。若失败,返回403 Forbidden。
- 上下文注入:将认证通过的用户身份和租户上下文注入到当前请求的上下文中(如Spring Security的SecurityContextHolder)。
架构建议:认证阶段只做“签名验证”和“Token过期检查”,不要在此阶段查询数据库。授权阶段才需要访问权限缓存或策略引擎。这种分离能显著降低认证服务的延迟。
2.3 拦截链路在SaaS中的位置与作用
在微服务或单体架构中,拦截链路通常位于网关层或应用层的最前端。对于多租户SaaS,拦截链路不仅是安全屏障,更是租户隔离的第一道防线。
2.4 拦截链路在SaaS中的分层职责
根据SaaS架构的成熟度,拦截链路通常分为两层:网关层拦截和应用层拦截。两者职责不同,不可互相替代。
| 拦截层级 | 典型组件 | 核心职责 | 失败处理 | 性能要求 |
|---|---|---|---|---|
| 网关层 | Kong、Spring Cloud Gateway、Envoy | Token格式校验、签名验证、黑名单检查、限流 | 直接返回401,不转发到后端 | 高(无状态,纯计算) |
| 应用层 | Spring Security Filter、Shiro、自定义Filter | 角色/权限校验、租户数据隔离、上下文注入 | 返回403,记录审计日志 | 中(可能涉及缓存查询) |
常见陷阱:很多团队只在网关层做认证,而将授权逻辑分散到各个业务服务中。这会导致权限策略不一致、租户隔离漏洞频发。正确的做法是:网关层只做认证,应用层通过统一的鉴权组件完成授权决策。
2.5 拦截链路与租户上下文的传递
在多租户SaaS中,拦截链路的一个重要产出是租户上下文(Tenant Context)。它必须在认证通过后,被安全地传递到后续的所有服务调用中。
2.6 拦截链路设计原则总结
- 无状态原则:网关层拦截器不应持有任何会话状态,所有认证信息必须从请求中提取。
- 最小泄露原则:拦截链路只暴露必要的身份信息给下游服务,避免传递完整Token。
- 失败安全原则:任何鉴权失败都应立即终止请求,不允许降级放行。
- 可观测原则:每次鉴权决策必须记录日志,包括决策结果、决策依据、耗时。
- 租户感知原则:所有拦截器必须感知租户上下文,确保数据隔离策略在链路最前端生效。