2. SSO 主流协议:原理与对比
单点登录(SSO)的实现依赖标准化的身份与授权协议。当前工业界最成熟的四种协议分别是 CAS、OAuth 2.0、SAML 和 OpenID Connect (OIDC)。理解它们的核心流程与适用场景,是设计异步任务编排下会话一致性的基础。
2.1 CAS 协议原理
CAS(Central Authentication Service)是 Yale 大学发起的开源 SSO 协议,专为 企业内部 Web 应用 的统一认证而设计。其核心是 票据(Ticket) 机制。
核心组件与票据
| 组件/票据 | 说明 |
|---|---|
| CAS Server | 集中式认证服务器,负责用户登录、票据发放与校验。 |
| CAS Client | 受保护的应用,拦截未认证请求并重定向到 CAS Server。 |
| TGT (Ticket Granting Ticket) | 用户登录成功后,CAS Server 在客户端浏览器中设置的长期票据(通常存储在 Cookie 中)。 |
| ST (Service Ticket) | 用户访问某个具体服务时,CAS Server 发放的一次性临时票据,由 CAS Client 验证。 |
典型认证流程
- 访问受保护资源:用户请求 App A,CAS Client 检测到未认证,重定向到 CAS Server 的登录页。
- 统一登录:用户输入凭证,CAS Server 验证成功后,生成 TGT(写入 Cookie)并发放 ST(作为参数重定向回 App A)。
- 服务票据校验:App A 的 CAS Client 拿着 ST 向 CAS Server 后台验证,验证通过后建立本地会话。
- 跨应用访问:用户访问 App B,CAS Client 检测到未认证,重定向到 CAS Server。此时 CAS Server 检测到 TGT Cookie 有效,直接生成新的 ST 并重定向回 App B,无需再次输入密码。
关键设计点: CAS 协议本身不处理授权(Authorization),只处理认证(Authentication)。所有应用共享同一个认证状态(TGT),但每个应用维护自己的本地会话。
2.2 OAuth 2.0 协议原理
OAuth 2.0 是一个 授权(Authorization)框架,允许第三方应用在用户授权的前提下,获取用户在资源服务器上的受保护资源(如 API、照片、联系人)。它不直接处理用户身份认证。
核心角色与授权模式
| 角色 | 说明 |
|---|---|
| Resource Owner | 用户,拥有资源的最终决定权。 |
| Client | 第三方应用,需要访问用户资源。 |
| Authorization Server | 认证与授权中心,发放 Access Token。 |
| Resource Server | 存储用户资源的 API 服务。 |
四种授权模式
- 授权码模式(Authorization Code):最安全、最常用。Client 先获取授权码,再用授权码换取 Access Token。适用于有后端的 Web 应用。
- 隐式模式(Implicit):简化流程,直接返回 Access Token(现已不推荐,因安全风险)。适用于纯前端应用。
- 密码模式(Resource Owner Password Credentials):用户直接向 Client 提供密码,Client 用密码换取 Token。仅适用于高度信任的 Client。
- 客户端模式(Client Credentials):Client 以自己的身份(而非用户身份)获取 Token,用于机器对机器的通信。
SSO 场景提示: OAuth 2.0 本身不是 SSO 协议,但它是构建现代 SSO 的基础。通过授权码模式,用户只需在 Authorization Server 登录一次,即可授权多个 Client 应用访问资源,间接实现了“一次登录,多处授权”的效果。
2.3 SAML 协议原理
SAML(Security Assertion Markup Language)是一个基于 XML 的开放标准,主要用于企业级 跨域 SSO。它通过 断言(Assertion) 在身份提供者(IdP)和服务提供者(SP)之间传递用户身份与属性信息。
核心角色与断言类型
| 角色 | 说明 |
|---|---|
| IdP (Identity Provider) | 身份提供者,负责用户认证并生成 SAML 断言。 |
| SP (Service Provider) | 服务提供者,依赖 IdP 的断言来授权用户访问。 |
| Principal | 用户主体。 |
三种断言类型
- 认证断言(Authentication Assertion):证明用户何时、通过何种方式登录。
- 属性断言(Attribute Assertion):传递用户的属性信息(如邮箱、角色、部门)。
- 授权决策断言(Authorization Decision Assertion):声明用户是否被允许执行特定操作。
典型流程(SP 发起)
- 访问 SP 资源:用户请求 SP 的受保护页面。
- 生成 AuthnRequest:SP 生成一个 SAML 认证请求,并重定向用户到 IdP。
- 用户认证:IdP 验证用户身份(如密码、MFA)。
- 生成 SAML Response:IdP 生成包含认证断言和属性断言的 SAML Response,通过浏览器 POST 回 SP。
- SP 验证断言:SP 验证 SAML Response 的数字签名,提取用户信息并建立本地会话。
异步任务编排的挑战: SAML 断言通常有严格的有效期(如 5 分钟)。在异步任务中,如果任务执行时间过长,可能导致断言过期。设计时需考虑断言刷新或使用长寿命的会话 Token 作为替代。
2.4 OpenID Connect (OIDC) 协议原理
OIDC 是在 OAuth 2.0 之上构建的 身份认证层。它解决了 OAuth 2.0 不处理用户身份的问题,通过引入 ID Token(JWT 格式)来标准化用户身份的传递。OIDC 是当前 Web 和移动端 SSO 的事实标准。
核心概念
| 概念 | 说明 |
|---|---|
| ID Token | JWT 格式的令牌,包含用户身份信息(iss、sub、aud、exp、name、email 等)。 |
| UserInfo Endpoint | 受保护的 API,Client 可用 Access Token 获取更详细的用户声明。 |
| Scope | OIDC 定义了标准 scope:openid(必须)、profile、email、address、phone。 |
| Claims | ID Token 或 UserInfo 中包含的用户属性键值对。 |
OIDC 认证流程(授权码模式)
- Client 发起认证请求:包含 scope=
openid,response_type=code。 - 用户登录并授权:用户向 Authorization Server 认证,并同意 Client 请求的 scope。
- 返回授权码:Authorization Server 重定向回 Client,附带授权码。
- Client 换取 Token:Client 用授权码向 Token Endpoint 请求,返回 Access Token 和 ID Token。
- Client 验证 ID Token:Client 验证 ID Token 的签名、iss、aud、exp 等字段,提取用户身份。
- (可选)获取 UserInfo:Client 用 Access Token 调用 UserInfo Endpoint,获取更多用户信息。
与 OAuth 2.0 的关键区别: OAuth 2.0 只关心“你能访问什么资源”(Access Token),而 OIDC 关心“你是谁”(ID Token)。在 SSO 场景中,OIDC 的 ID Token 直接提供了标准化的用户身份,使得多个应用可以共享同一个用户会话。
2.5 四大协议对比总结
| 特性 | CAS | OAuth 2.0 | SAML | OpenID Connect |
|---|---|---|---|---|
| 主要目的 | 认证 (SSO) | 授权 | 认证 + 属性传递 | 认证 (SSO) + 授权 |
| 消息格式 | 自定义 Ticket | JSON (Token) | XML (Assertion) | JWT (ID Token) + JSON |
| 传输协议 | HTTP 重定向 + 后台验证 | HTTP 重定向 + JSON API | HTTP POST / Redirect Binding | HTTP 重定向 + JSON API |
| 适用场景 | 企业内部 Web 应用 | 第三方 API 授权 | 企业级跨域 SSO | 现代 Web / 移动端 SSO |
| 是否支持注销 | 支持 (SLO) | 不原生支持 | 支持 (SLO) | 支持 (RP-Initiated Logout) |
| 异步任务友好度 | 低(Ticket 短生命周期) | 中(Token 可刷新) | 低(Assertion 短生命周期) | 高(JWT 可离线验证,支持 Refresh Token) |
课程选型建议: 在异步任务编排的 SSO 设计中,OIDC 是最佳选择。其 JWT 格式的 ID Token 可以离线验证,配合 Refresh Token 机制,能很好地解决异步任务中会话过期的问题。CAS 和 SAML 在异步场景下需要额外的会话保持机制。