单点登录(SSO)全景指南:从原理剖析到落地实战
在现代企业架构中,微服务、SaaS 应用和内部系统层出不穷。用户往往需要记住十几套账号密码,每访问一个新系统就要重新登录一次。这不仅用户体验极差,也增加了运维管理的成本和安全风险。
单点登录(Single Sign-On, SSO) 正是为了解决这一痛点而生。它的核心理念是:"一次登录,全网通行"。
本文将深入拆解 SSO 的核心原理,对比主流协议(CAS、OAuth2、OIDC、SAML),并提供一套可落地的架构设计方案。
一、什么是单点登录(SSO)?
1. 核心定义
SSO 是一种身份认证方案,允许用户使用一套凭证(用户名/密码、生物特征等)登录一个中心化的认证系统后,即可访问所有互相信任的应用系统,而无需再次输入凭证。
2. 传统会话 vs. SSO 会话
传统模式 :
系统 A 有独立的 Session/Cookie。
系统 B 有独立的 Session/Cookie。
用户访问 A 需登录,访问 B 需再次登录。
缺点:体验割裂,密码管理混乱,注销困难(需分别退出)。
SSO 模式 :
存在一个统一的认证中心(Identity Provider, IdP)。
所有业务系统(Service Provider, SP)信任该认证中心。
用户只需在认证中心登录一次,访问任何 SP 时,SP 会向认证中心确认用户身份,自动完成登录。
二、核心原理:SSO 是如何工作的?
无论采用哪种协议,SSO 的底层逻辑都依赖于**"票据(Ticket/Token)"**的传递和验证。最经典的流程如下:
场景模型
用户:浏览器端。
认证中心 (SSO Server):负责统一登录、发证。
应用系统 A/B (Client):受保护的业务系统。
共享域名/重定向机制:用于跨域传递状态。
标准交互流程(以基于重定向的 Token 模式为例)
用户访问应用 A:
用户请求 app-a.com。
应用 A 发现本地无有效会话,拦截请求,重定向用户到 sso-server.com/login?redirect=app-a.com。
用户在认证中心登录:
用户看到 SSO 服务器的登录页。
输入账号密码,SSO 服务器验证通过。
关键步骤 :SSO 服务器生成一个全局会话(Global Session),并创建一个授权码(Authorization Code)或票据(Ticket)。
SSO 服务器重定向回应用 A:app-a.com/callback?code=xyz123。
应用 A 换取用户信息:
应用 A 拿到 code,在后台向 SSO 服务器发起请求:POST /verify?code=xyz123&app_id=A。
SSO 服务器验证 code 有效性,返回用户信息(如 UserID, Role)和一个访问令牌(Access Token)。
应用 A 建立本地会话(Local Session),允许用户访问。
用户访问应用 B(免登过程):
用户点击链接访问 app-b.com。
应用 B 发现无本地会话,重定向到 sso-server.com/login?redirect=app-b.com。
关键点:此时浏览器携带了 SSO 服务器的全局 Cookie(步骤 2 中建立的)。
SSO 服务器检测到用户已登录(全局会话有效),无需用户再次输入密码。
SSO 服务器直接生成新的 code,重定向回 app-b.com/callback?code=abc456。
应用 B 拿 code 换 Token,建立本地会话。
结果:用户无感知地进入了系统 B。
单点注销(SLO):
用户在任一系统点击"退出"。
该系统通知 SSO 服务器销毁全局会话。
SSO 服务器遍历所有注册过的子系统,发送回调请求,通知它们销毁本地会话。
三、主流协议与方案选型
实现 SSO 有多种协议,选择哪种取决于你的应用场景(内部系统、互联网开放平台、企业间互联)。
协议/方案
全称
特点
适用场景
复杂度
CAS
Central Authentication Service
老牌、简单、基于 Ticket。由耶鲁大学开源。
高校、传统企业内部系统、Java 生态。
⭐⭐
OAuth 2.0
Open Authorization
授权标准,非认证标准。主要用于第三方资源访问授权。
微信/QQ 登录、API 授权。
⭐⭐⭐
OIDC
OpenID Connect
基于 OAuth 2.0 构建的身份认证层。返回 ID Token (JWT)。
现代互联网应用首选,移动端、前后端分离架构。
⭐⭐⭐⭐
SAML 2.0
Security Assertion Markup Language
基于 XML,极其严谨复杂,企业级标准。
跨国大企业、政府机构、遗留系统集成。
⭐⭐⭐⭐⭐
LDAP/AD
Lightweight Directory Access Protocol
目录服务协议,常作为 SSO 的后端数据源。
企业内部员工账号统一管理。
⭐⭐⭐
深度解析:为什么现在推荐 OIDC?
虽然 CAS 很简单,但它在移动端支持和标准化方面略显老旧。SAML 太重且解析 XML 性能较差。 OIDC (OpenID Connect) 是目前业界的事实标准:
基于 JSON 和 JWT:轻量级,易于解析,适合前后端分离。
标准化用户信息 :定义了标准的 id_token,包含用户身份信息(UserInfo Endpoint)。
生态丰富:Keycloak, Auth0, Okta, Spring Security OAuth2 等主流框架均原生支持。
灵活:支持授权码模式(最安全)、隐式模式(已废弃)、密码模式(不推荐)等。
四、落地实现方案:自研 vs. 集成
方案 A:使用成熟开源产品(强烈推荐)
对于大多数团队,不要重复造轮子。身份安全关乎身家性命,成熟的开源产品经过了全球社区的审计和打磨。
1. Keycloak (RedHat 出品)
特点:功能最全,支持 OIDC, SAML, CAS, LDAP 集成,自带管理控制台,支持社交登录,支持多因素认证(MFA)。
优势:开箱即用,社区活跃,文档丰富。
部署:支持 Docker/K8s 部署。
适用:绝大多数中大型项目。
2. MaxKey / Casdoor
MaxKey:国内开源,对中文支持好,符合国内信创标准。
Casdoor:Go 语言编写,高性能,UI 美观,易于集成。
实施步骤:
部署 Keycloak 服务。
在 Keycloak 创建 Realm(租户),配置用户数据库(或对接 LDAP/AD)。
为每个业务系统创建 Client(客户端),获取 Client-ID 和 Secret。
业务系统引入 SDK(如 spring-boot-starter-oauth2-client),配置 issuer-uri 和 client-id。
代码层面只需添加 @PreAuthorize 等注解即可保护接口。
方案 B:基于 Spring Security 自研(仅限特殊需求)
如果业务极其特殊,无法使用标准产品,可基于 Spring Security + Redis 自研简易 SSO。
核心组件设计:
SSO-Auth-Server :
提供 /login 页面。
生成全局 Token (UUID),存入 Redis (key: sso_token:xxx, value: userId, expire: 2h)。
提供 /validate 接口供子系统校验 Token。
业务子系统 Filter :
拦截请求,检查本地 Cookie。
无 Cookie 则重定向至 SSO-Auth-Server。
接收回调,调用 /validate,成功后写入本地 Cookie。
⚠️ 自研风险:
容易忽略 CSRF 攻击、重放攻击。
单点注销(SLO)逻辑复杂,容易遗漏。
缺乏审计日志和多因素认证支持。
结论 :除非为了学习或极度受限的环境,否则生产环境不建议自研核心认证逻辑。
五、关键挑战与解决方案
1. 跨域 Cookie 问题
浏览器的同源策略限制 Cookie 只能在同域下传输。
解决 :SSO 服务器通常部署在独立域名(如 sso.example.com)。业务系统通过重定向将用户带到该域名下建立全局 Cookie,然后再重定向回业务域名。这是标准 OIDC/CAS 流程天然解决的,不需要前端手动操作 Cookie。
2. 单点注销(SLO)的可靠性
如何确保用户退出后,所有子系统都退出?
前端 iframe 法(传统):SSO 服务器返回一个页面,里面包含所有子系统的注销 iframe 链接。但现代浏览器对第三方 Cookie 和 iframe 限制越来越严,此法逐渐失效。
后端回调法(推荐) :
子系统登录时,向 SSO 服务器注册一个"注销回调 URL"。
用户注销时,SSO 服务器遍历注册列表,向后端发起 HTTP 请求通知注销。
难点:需处理网络超时、子系统宕机。通常采用"最终一致性"策略,配合消息队列(MQ)广播注销事件。
3. 性能与高可用
认证中心是所有流量的入口,一旦挂掉,全公司系统瘫痪。
集群部署:SSO 服务必须多实例部署,前置负载均衡(Nginx/SLB)。
Session 共享:全局会话数据必须存储在外部缓存(Redis Cluster),不能存在内存中。
异地多活:对于超大规模系统,需考虑认证中心的异地容灾。
4. 安全性加固
强制 HTTPS:所有 Token 传输必须加密。
短效 Token:Access Token 有效期设短(如 15 分钟),配合 Refresh Token 机制。
防重放:授权码(Code)只能使用一次,用完即焚。
审计日志:记录所有登录、注销、授权失败的行为。
六、总结与建议
单点登录(SSO)是现代 IT 架构的基础设施。它不仅仅是方便用户少输几次密码,更是企业统一身份治理、提升安全水位的关键一步。
落地建议路线图:
小型项目/初创期:直接使用云厂商提供的身份服务(如 Auth0, 阿里云 IDaaS),零运维成本。
中型项目/成长期 :私有化部署 Keycloak 或 Casdoor。利用其成熟的 OIDC 协议对接各业务系统。
大型国企/复杂遗留系统:可能需要混合模式。核心新系统用 OIDC,老旧 Java 系统用 CAS,Windows 域环境用 AD/LDAP 联邦。此时 Keycloak 也能作为聚合层(Identity Broker)来统一对接。
最后记住 :身份认证是安全链条中最脆弱的一环。不要试图自己发明加密算法或认证流程,站在巨人的肩膀上(使用标准协议和成熟产品),才是最高效、最安全的选择。