4. 会话生命周期管理
SSO 会话并不是“登录成功后一直有效”的静态凭证,而是一条有明确起止的生命周期。企业里绝大多数会话类安全事故,并不是加密算法被攻破,而是生命周期某一阶段的控制点缺失:创建时没有绑定设备与来源、维持时缺少风险感知、续期时无限延长、注销时只清了本地 Cookie 而没动中心会话。理解这条链路上每个阶段“谁在写、谁在读、谁在失效”,比记住某个协议细节更有价值。
一、创建阶段:把身份、设备与上下文绑定在一起
会话创建发生在 IdP 完成认证、向 SP 签发断言或令牌的那一刻。此时最关键的动作是生成一个不可预测的会话标识,并把它与三类信息绑定:主体身份(sub)、客户端上下文(设备指纹、User-Agent、IP 段)、以及认证强度(是否 MFA、认证时间、认证方法)。
常见漏洞有三类。第一是会话固定(Session Fixation):攻击者先获取一个会话 ID,诱导受害者用该 ID 完成登录,登录后服务端未重新生成会话标识,攻击者即可复用同一 ID 进入已认证会话。防御要点是认证成功后必须调用会话重建,使旧 ID 立即失效。第二是断言重放:SAML 断言或 OIDC 授权码缺少一次性校验(如 InResponseTo、nonce、jti),被截获后可在有效期内重复使用。第三是令牌过度授权:创建时把 scope 或角色一次性放大,后续无法收敛。
下面这张图给出会话从创建到注销的完整生命周期,以及每个阶段对应的核心控制点与典型失效点。
二、维持阶段:从“一次认证”到“持续信任”
会话建立后,真正的安全博弈发生在维持阶段。核心原则是:信任不是一次性的,而是每次请求都要重新确认的。服务端在每次请求中至少要校验四件事:令牌签名是否有效、是否在有效期内、会话是否仍处于活跃状态、当前请求上下文是否与创建时绑定的上下文一致。
空闲超时(Idle Timeout)与绝对超时(Absolute Timeout)是两个必须同时存在的参数。空闲超时指会话在无操作一段时间后失效,例如 30 分钟;绝对超时指无论是否活跃,会话从创建起最多存活多久,例如 8 小时或 12 小时。只设空闲超时,攻击者可以持续发请求“保活”;只设绝对超时,用户离开工位后会话仍可能被利用。两者叠加才能覆盖“人走了”和“人一直在但设备被控”两种场景。
设备指纹与 IP 段比对是维持阶段最有效的异常发现手段。当同一会话突然从不同 ASN、不同国家或不同设备指纹发起请求时,应触发风险评分。评分超过阈值时,可采取降级措施:要求重新 MFA、限制敏感操作、或直接终止会话。这里要注意,IP 会因移动网络切换而合理变化,因此不宜把 IP 完全固定,而应使用“IP 段 + 地理速度”组合判断,例如两次请求间隔 5 分钟却跨越 2000 公里,即判定为不可能旅行。
三、续期阶段:刷新令牌的轮换与上限
现代 SSO 普遍采用“短生命周期访问令牌 + 长生命周期刷新令牌”的结构。访问令牌通常 5~15 分钟,刷新令牌 7~30 天。续期阶段最大的风险是刷新令牌被窃取后长期复用。防御的核心是刷新令牌轮换:每次使用刷新令牌换取新访问令牌时,同时签发一个新的刷新令牌,并立即作废旧的刷新令牌。
轮换必须配合“重放检测”。如果服务端收到一个已经被作废的刷新令牌,说明该令牌可能已被攻击者复制,此时应立刻撤销该会话对应的整个令牌族(Token Family),强制用户重新认证。此外,续期不能无限进行,必须设置绝对超时上限。例如刷新令牌本身最长 30 天,且每次续期时重新评估设备与风险,风险升高则拒绝续期。
续期请求示例(OIDC Refresh Token Grant)
POST /token
grant_type=refresh_token
refresh_token=rt_9f3a...c21
client_id=corp-portal
服务端处理逻辑:
1. 校验 rt_9f3a...c21 是否在有效刷新令牌集合中
2. 若不在(已被轮换作废)→ 判定重放,撤销整个 Token Family
3. 若在 → 签发新 access_token(10min)与新 refresh_token
4. 将 rt_9f3a...c21 标记为已使用并作废
5. 检查会话创建时间是否超过绝对超时(如 30 天)→ 超过则拒绝续期
四、注销阶段:单点登出必须“全局生效”
注销是最容易被低估的阶段。很多系统只做了本地 Cookie 清除,用户以为已退出,但 IdP 中心会话仍然有效,攻击者拿到该会话即可免密进入其他已登录的 SP。完整的注销应包含三个动作:第一,使 IdP 中心会话失效;第二,通过 SLO(Single Logout)协议向所有已建立会话的 SP 广播注销通知;第三,撤销该会话关联的访问令牌与刷新令牌。
SLO 的工程难点在于“广播的可靠性”。如果某个 SP 暂时不可达,注销通知可能丢失,导致该 SP 仍保留本地会话。实践中通常采用“中心会话失效 + SP 短时校验”的组合:SP 在每次请求时向 IdP 校验会话状态(或使用短生命周期令牌),即使 SLO 通知丢失,SP 也会在令牌过期后自然失效。对于高敏感系统,可进一步要求 SP 在关键操作前主动调用 IdP 的会话校验接口。
常见误区:把“关闭浏览器”等同于“注销会话”。关闭浏览器只清除本地 Cookie,中心会话和刷新令牌仍然有效。企业应在培训中明确区分“关闭标签页”“退出当前应用”“全局注销”三种操作的实际效果。
五、各阶段控制点速查
| 阶段 | 核心控制点 | 关键参数示例 | 典型漏洞 |
|---|---|---|---|
| 创建 | 认证后重建会话 ID、绑定设备与来源、断言一次性校验 | 会话 ID 长度 ≥128 bit;nonce 有效期 ≤5 min | 会话固定、断言重放、scope 过大 |
| 维持 | 每请求校验、空闲超时、设备指纹比对、并发限制 | 空闲超时 30 min;并发会话 ≤3 | 会话永活、令牌被窃无感知 |
| 续期 | 刷新令牌轮换、重放检测、绝对超时、风险重评估 | 访问令牌 10 min;刷新令牌 30 天;绝对超时 12 h | 刷新令牌不轮换、无限续期 |
| 注销 | 中心会话失效、SLO 广播、令牌撤销、审计记录 | SLO 通知重试 3 次;令牌撤销延迟 ≤5 s | 只清本地 Cookie、SLO 未广播 |
把四个阶段串起来看,会话安全本质上是一道“时间与上下文”的约束题:创建时绑定得越紧,维持时校验得越勤,续期时收敛得越果断,注销时清理得越彻底,攻击者能利用的窗口就越小。企业落地时不必一次追求全部控制点,但应优先补齐三个最容易被利用的缺口——认证后重建会话 ID、刷新令牌轮换、以及中心会话先失效的全局注销。