SSO 单点登录系统设计与实现文档
1. 系统概述
1.1 项目背景
本单点登录(SSO)方案旨在为多个业务系统提供统一的身份认证服务。
单点登录(SSO)系统允许用户通过一次登录访问多个相互信任的应用系统。本文档详细描述了基于域名认证和两种认证模式(Simple 和 Ticket)的 SSO 实现方案。
方案的核心设计支持两种场景:同二级域名下的Cookie共享与跨域情况下的Ticket验证。 其核心思想是建立一个独立的认证中心(SSO Server),所有业务系统(SSO Client)在用户访问受保护资源时,均重定向至该中心进行身份验证。验证通过后, 根据业务系统与认证中心的域名关系,采用不同的方式传播登录状态,最终实现“一次登录,全网通行”的目标
1.2 演示地址
| 系统名称 | 访问地址 | 说明 |
|---|---|---|
| 业务演示 Demo 1 | https://demo1.epochcloud.cn | 测试1,点击登录跳转 |
| 业务演示 Demo 2 | https://demo1.epochcloud.cn | 测试2,点击登录跳转 |
| 单点登录 | https://sso.epochcloud.cn |
1.3 设计目标
- 统一认证:用户一次登录,多系统免登
- 安全可靠:防止未授权访问和数据泄露
- 灵活扩展:支持多种认证模式和业务场景
- 易于集成:提供标准化的接入流程
1.4. 技术架构
- 前端业务层:多个业务前端,可能部署在不同域名下。
- SSO 认证中心:统一认证中心,负责用户认证和令牌管理。
- 后端业务层:多个业务后端,共享同一后台,通过 SSO 认证中心实现单点登录。
1.5 技术栈
- 后端框架:Spring Boot3
- 缓存中间件:Redis
- 数据库:MySQL
- 前端框架:Vue 3(SSO登录页)
- 安全组件:Sa-Token
2. 架构设计
2.1 系统架构图
3.核心流程设计
总体流程图
3.1 登录认证初始化流程
业务前端通过调用 /system/auth/getSsoAuthUrl 接口获取 SSO 登录地址。请求参数包括:
clientLoginUrl:单点登录本地的客户端 URL。back:回调地址。
接口返回单点登录地址,前端跳转到该地址。例如:
https://sso.epochcloud.cn/login?client=sso-client&redirect=https://demo1.epochcloud.cn/sso-login?back=https://demo1.epochcloud.cn/index
地址跳转:业务后端根据传入参数,生成指向认证中心(SSO Server)的登录地址。 该地址需包含客户端标识 (client)、认证模式 (mode) 及编码后的回跳地址 (redirect),
前端随后跳转至此地址。
域名安全校验:认证中心在接收跳转请求时,需对请求中的 client 参数及来源域名进行校验,确保其为已注册且受信任的客户端,防止未授权的系统发起登录请求,这是保障系统安全的重要一环。
3.2 统一认证与状态传播
用户被重定向至认证中心的登录页面后,进行核心的身份认证与状态分发。
用户认证:用户在认证中心页面输入账号密码并提交。认证中心后端验证凭证有效性。 认证成功后的分支处理:登录成功后,系统根据 redirect 参数和 mode 参数决定如何传播会话状态,主要分为以下两种模式:
A. 同域Cookie共享模式 (mode=simple):
此模式适用于业务系统与认证中心处于同一父域名(二级域名)下的场景(例如,SSO域为 sso.epochcloud.cn,业务域为 demo1.epochcloud.cn)。 认证中心在验证成功后,会生成一个代表用户身份的令牌(Token),并将其写入一个 Domain属性设置为父域名(如 .epochcloud.cn) 的Cookie中。由于Cookie遵循同源策略,设置父域后,所有子域均可读取此Cookie。 随后,认证中心直接重定向回 back 参数指定的业务系统地址。业务系统在加载时,其前端或后端(因Cookie在请求中自动携带)即可读取到此共享Cookie中的Token,完成自动登录,用户无感知。
B. 跨域Ticket重定向模式 (mode=ticket):
此模式适用于业务系统与认证中心域名完全独立的场景,是解决Cookie无法跨域共享的标准方案。 认证中心登录成功后,会生成一个一次性的、有时效性的授权票据(Ticket),并将Ticket作为URL参数,附加在重定向地址(redirect)后,跳转回业务系统指定的回调地址(例如:https://demo1.epochcloud.cn/sso-login?ticket=xyz123abc&back=...)。 业务系统的回调页面(如 /sso-login)接收到该Ticket后,前端或后端需立即调用认证中心提供的凭证验证接口(如 doLoginByTicket),将此Ticket提交回认证中心进行校验。 认证中心验证Ticket有效后,返回该Ticket对应的用户身份信息及一个仅限当前业务域名使用的Token。业务系统获取此Token后,将其保存在本地(如写入仅限自身域名的Cookie,或存储在LocalStorage中并在后续请求的Header中携带),从而完成在当前系统的登录。
3.3 已登录状态下的访问流程(免登录)
一旦用户已在某个系统通过上述任一方式完成登录,访问其他信任系统时将享受免登录体验。
用户访问新业务系统(如 demo2.epochcloud.cn)。 该系统检查本地登录状态。在模式A下,由于父域Cookie已存在,系统可直接读取Token并验证;在模式B下,本地无有效会话。 无论本地检查结果如何,系统都会将用户重定向至认证中心。此时,认证中心会检查浏览器中属于自身域名(sso.epochcloud.cn)的Cookie。 由于用户已在认证中心全局登录,该Cookie有效。认证中心将不再展示登录页,而是直接根据新访问系统的配置(其注册的mode),再次执行上述 “2.认证成功后的分支处理” 流程,或通过Cookie共享,或通过Ticket传递,帮助用户在新系统自动完成登录。
3.4 全局登出流程
为确保安全,登出操作需在所有系统中同步生效。
用户在任一业务系统发起登出请求。 该业务系统调用认证中心的全局登出接口。 认证中心执行两项关键操作:① 使服务器端的会话或Token失效(例如,删除Redis中存储的该用户登录记录);② 清除或过期化由认证中心颁发的所有相关Cookie(包括其自身域和父域的Cookie)。 认证中心通知所有已登录的业务系统(可通过前端广播或后端回调),各业务系统接收到通知后,清除自身的本地会话(如Token或Cookie)。 登出完成后,用户再次访问任何系统,都将被重定向至登录页,要求重新认证。
4.主要接口设计
4.1 获取SSO登录URL
接口地址:/system/auth/getSsoAuthUrl
请求方式:GET
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| clientLoginUrl | string | 是 | 单点登录本地的客户端 URL |
| back | string | 是 | 回调地址 |
返回数据:
{
"code": 200,
"data": "https://sso.epochcloud.cn/login?client=sso-client&redirect=..."
}
4.2 获取回调地址接口
接口地址:/getRedirectUrl
请求方式:GET
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| redirect | string | 是 | 回调地址 |
| client | string | 是 | 客户端标识 |
| mode | string | 否 | 认证模式(simple/ticket) |
返回数据:
- Simple 模式:直接返回回调地址。
- Ticket 模式:返回带 Ticket 参数的回调地址。
4.3 Ticket 登录接口
接口地址:/doLoginByTicket
请求方式:POST
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ticket | string | 是 | Ticket 令牌 |
返回数据:
{
"code": 200,
"data": {
"token": "xxx"
}
}
5.关键设计要点与考量
域名规划与Cookie配置:为实现同域共享,所有系统(认证中心及业务系统)应规划在同一父域名下。设置Cookie时,必须正确配置domain(如.epochcloud.cn)、path(通常为/)、httpOnly(建议为true防XSS)、secure(HTTPS环境下为true)和SameSite(通常为Lax)等属性,以兼顾功能、安全与浏览器兼容性。 Token与Ticket的安全与管理:
Token:应使用JWT等加密技术生成,包含用户标识、过期时间等信息,并签名防篡改。其有效期应适中,并考虑续期机制。 Ticket:作为一次性的临时凭证,有效期应非常短(如一次有效),且使用后立即在服务端作废,防止重放攻击。
安全加固:
防CSRF:利用Cookie的SameSite属性,并可在关键请求中添加CSRF Token。 防XSS:设置Cookie为httpOnly,防止被前端JavaScript窃取。 传输安全:生产环境务必使用HTTPS,并设置Cookie的secure属性为true。
状态同步与用户体验:
各业务系统需在前端(路由守卫、请求拦截器)和后端(拦截器)对Token有效性进行校验,无效时统一跳转至认证中心。 登出需保证所有系统状态同步清除,避免出现“一个系统退出,其他系统仍可访问”的安全漏洞。
6.总结
本方案设计了一个灵活且安全的单点登录系统。它通过一个统一的认证中心,巧妙地结合了 “同域Cookie共享” 的高效便捷与 “跨域Ticket重定向” 的广泛适应性。方案明确了从登录初始化、认证状态分发、免登录访问到全局登出的完整闭环流程,并强调了安全配置与状态同步等关键实施要点,能够满足后台统一但前端可多域名部署的复杂业务场景,在提升用户体验的同时,保障了系统的安全性与可维护性。