Skip to content

如何实现一个单点登录(SSO)系统?如果有多个子系统,用户只需登录一次即可访问所有系统 ​

  • 标签:后端、系统设计、场景题、单点登录

🏛 业务架构师 ​

单点登录(SSO)设计,我先点业务本质:SSO 不只是省去多次登录,它是集团用户资产的统一——一个 UID 打通全生态(交叉营销、统一风控、统一合规治理的基础)。理解这层,才知道认证中心该按什么标准建设。

核心架构:认证中心 + 各子系统

登录流程(CAS 票据模式)

用户访问子系统A(未登录) → 302跳转认证中心(带service=A的地址)
认证中心: 展示统一登录页 → 校验账号密码 → 创建全局会话(TGT, 写Cookie到认证中心域)
        → 302回跳A, 携带一次性ticket(ST)
子系统A: 拿ticket去认证中心校验 → 换取用户信息 → 建立A的本地会话
用户再访问子系统B → 跳认证中心时全局会话Cookie仍有效 → 免密直接发ticket给B

单点登出:认证中心销毁全局会话 → 回调通知所有已登录子系统销毁本地会话(登出注册表)。漏通知就有"幽灵会话",所以子系统要同时在认证中心登记。

关键设计点

  1. ticket 安全:一次性(用后即焚)、短时效(30 秒~5 分钟)、只走后端校验(子系统后端拿 ticket 换信息,浏览器只中转)——防票据劫持
  2. 会话分层:全局会话(认证中心,长效)+ 各系统本地会话(短效,自主管理)——子系统挂了不影响别人,认证中心压力小(只在登录时交互)
  3. Token 模式变体:现代做法认证中心签发 JWT/ OAuth2 token,网关统一验签——微服务架构下更流行,两者常混合(认证中心 + 网关统一鉴权)
  4. 记住登录态与安全平衡:金融类子系统可要求二次认证(访问支付要重新验密)——SSO 的便利不能架空敏感操作的风控

业务视角收尾:SSO 项目的隐性收益是统一登录数据——全产品的用户活跃视图、统一账号地图,这是增长团队的基础设施。同时认证中心是全公司可用性单点,必须按最高等级建设(多活 + 容灾),它挂了等于全业务闭门。

🏗 系统架构师 ​

SSO 的核心是认证中心(CAS/OAuth2 思想)+ 各子系统免登,我按登录流程、登出、架构要点讲。

1. 核心流程(授权码模式)

首次登录子系统 A:

  1. 用户访问 A,A 发现无本地会话,重定向到认证中心:/authorize?redirect_uri=A回调&ticket参数
  2. 认证中心展示登录页(此时用户还没登录过),用户提交账号密码 + 验证码
  3. 认证中心校验通过,创建全局会话(TGC,存在认证中心域的 Cookie),生成一次性授权码 code,302 回 A
  4. A 的后端拿 code 换 token(服务端调用,安全),认证中心校验 code 一次性有效,返回用户信息/JWT
  5. A 建立本地会话(自己的 Cookie/JWT),完成登录

访问子系统 B(免登的关键):重定向到认证中心 → 浏览器自动带上 TGC Cookie → 认证中心发现全局会话有效,不再弹登录页,直接发 code 给 B → B 换 token 建本地会话——用户感知"登录一次,处处通行"。

2. 关键设计点

  • code 一次性 + 短时效(5 分钟):防重放;code 与 redirect_uri 绑定防钓鱼
  • 双层会话:全局会话(认证中心)+ 各系统本地会话,token 用 JWT 的话本地免存
  • 登出(单点登出):认证中心销毁全局会话 + 通知各子系统销毁本地会话(回调各系统登出接口或前端广播);JWT 方案则靠黑名单/版本号
  • 安全:全链路 HTTPS、state 防 CSRF、密码错误限流防爆破、敏感操作二次认证

3. 架构级要求:认证中心自身集群化高可用(见 104 题);会话/临时凭据存 Redis(TGC、code、token 黑名单);协议上现代选择直接用 OAuth2/OIDC 标准而非私有协议,接入标准化(SAML 留给企业内老系统)。

💻 全栈开发专家 ​

SSO 我按 2026 年主流做法回答:认证中心基于 OIDC(OAuth2 演进),子系统统一对接,自研则 CAS 模型。

核心架构

text
用户 → 子系统A(未登录)→ 302 跳转认证中心 /authorize
认证中心:登录页 → 校验账号 → 302 回 redirect_uri?code=xxx&state=xxx
子系统A:后端用 code + clientSecret 换 token(服务端对服务端)
       → 拿到 id_token(JWT) + access_token → 建立自己的会话 → 放行
子系统B:跳认证中心时发现已有 SSO 会话 Cookie → 免登录直接发 code

登录一次的关键:认证中心的会话 Cookie 建立在认证中心域名下,子系统 A 登录后,子系统 B 跳转认证中心时自动带上该 Cookie,认证中心识别为已登录直接下发 code,用户无感。

关键技术点

  • 令牌:id_token 用 JWT(RS256 签名),子系统本地用公钥验签(JWKS 端点拉公钥并缓存),不用每次远程校验,认证中心压力小。
  • state 参数:防 CSRF,随机值绑定会话。
  • code 一次性 + 5 分钟有效:防截获重放,配合 PKCE(公开客户端)。
  • 单点登出:认证中心维护会话注册表(哪些子系统登录过),登出时逐个回调子系统清除会话 + JWT 进黑名单(或短时效 + refresh 轮换,避免维护黑名单)。

工程落地

  • 现成方案:Keycloak、Spring Authorization Server、Casdoor,别手搓登录全链路(密码加密、防爆破、MFA 都是坑)。
  • 同父域名子系统可简化为"顶级域 Cookie + Redis 共享会话",成本最低,跨域才需要完整跳转流程。

坑:回调域名白名单要严格校验(防开放重定向);JWT 别塞敏感信息(只是 base64 不是加密)。