详述单点登录(SSO)

一、SSO核心准备

在讲流程前,先明确核心角色和基础约束,这是理解流程的关键:

1. 核心角色
角色 职责 举例
用户(User) 访问各个业务系统,需要完成身份认证的终端使用者 员工、普通用户
IdP(身份提供商) 统一的身份认证中心,负责验证用户身份、颁发认证凭证(token)、管理全局会话 企业登录中心、微信开放平台、OAuth2.0授权服务器
SP(服务提供商) 依赖IdP完成认证的业务系统,信任IdP颁发的凭证,为用户提供具体服务 企业OA、CRM、报销系统、电商子站
2. 技术前提(保障流程安全/可行)
  • 通信协议:所有交互必须基于HTTPS(防止token/账号密码被中间人窃取);
  • 域名策略 :
    • 同域场景:IdP和所有SP属于同一主域名(如idp.company.com、oa.company.com、crm.company.com),Cookie可跨子域共享,流程更简单;
    • 跨域场景:IdP和SP域名不同(如idp.com、sp1.com、sp2.com),需通过URL重定向、PostMessage或第三方Cookie(需浏览器允许)完成凭证传递;
  • 凭证类型 :IdP通常颁发两种token(兼顾安全和易用):
    • access_token(访问令牌):短期有效(1小时内),供SP验证用户身份;
    • refresh_token(刷新令牌):长期有效(7天),用于过期后刷新access_token,通常存储在IdP的HttpOnly Cookie中。

场景1:用户首次访问某SP(如OA系统)的完整登录流程(核心)

这是SSO的基础流程,所有后续免登都依赖这次认证:

步骤 执行主体 具体动作(技术细节) 核心目的
1 用户 → SP1服务器 用户在浏览器输入OA地址(https://oa.company.com),发起HTTP请求 访问目标业务系统
2 SP1服务器 1. 检测到SP1本地无用户会话(无Cookie/sessionid); 2. 生成唯一state参数(防CSRF攻击); 3. 返回302重定向响应,跳转到IdP登录页:https://idp.company.com/login?redirect_uri=https://oa.company.com/callback&state=xxx 引导用户到统一登录中心
3 IdP服务器 1. 检测到IdP无全局会话(浏览器Cookie中无IdP的sessionid); 2. 返回IdP登录页面(账号密码表单) 要求用户完成身份验证
4 用户 → IdP服务器 输入账号密码,提交登录表单(HTTPS POST请求) 提交身份凭证
5 IdP服务器 1. 验证账号密码(对比数据库/LDAP); 2. 验证通过:生成IdP全局会话(sessionid),通过Set-Cookie存入浏览器(设置HttpOnly+Secure+SameSite=Strict); 3. 生成access_token(JWT格式,含用户ID/权限,私钥签名)和refresh_token 完成身份认证,生成全局凭证
6 IdP服务器 返回302重定向响应,跳转到SP1的回调地址,并携带参数:https://oa.company.com/callback?token=xxx&state=xxx 把token传递给SP1
7 SP1服务器 1. 验证state参数(和步骤2生成的一致,防CSRF); 2. 向IdP发起验证请求:https://idp.company.com/verify_token?token=xxx; 3. 等待IdP返回验证结果 确认token是IdP颁发且未篡改
8 IdP服务器 1. 校验token的签名(用公钥验证)、有效期、用户状态; 2. 返回验证结果(合法,附带用户基础信息) 确认token合法性
9 SP1服务器 1. 验证通过:创建SP1本地会话(生成SP1的sessionid,存入Cookie); 2. 返回OA系统页面(用户已登录状态) 完成SP1的登录,允许访问

场景2:用户已登录IdP,访问其他SP(如CRM系统)的免登流程

这是SSO的核心价值------一次登录,多系统通行:

步骤 执行主体 具体动作(技术细节) 核心目的
10 用户 → SP2服务器 输入CRM地址(https://crm.company.com),发起HTTP请求 访问第二个业务系统
11 SP2服务器 1. 检测到SP2无本地会话; 2. 生成state参数; 3. 重定向到IdP:https://idp.company.com/login?redirect_uri=https://crm.company.com/callback&state=yyy 引导到IdP验证是否已登录
12 IdP服务器 1. 检测到浏览器Cookie中携带IdP的sessionid(全局会话有效); 2. 无需展示登录页,直接生成新的access_token(针对SP2) 识别用户已登录,免登
13 IdP服务器 重定向到SP2的回调地址,携带token=zzz&state=yyy 传递token给SP2
14 SP2服务器 验证state,并向IdP发起verify_token请求 验证token合法性
15 IdP服务器 返回token验证结果(合法) 确认身份
16 SP2服务器 创建SP2本地会话,返回CRM系统页面(已登录状态) 完成SP2免登,允许访问

场景3:全局登出流程(所有SP同步登出)

SSO不仅要"一次登录",还要"一次登出",确保所有系统同步退出:

步骤 执行主体 具体动作(技术细节) 核心目的
17 用户 → SP1服务器 在OA系统点击"退出登录"按钮,发起登出请求 触发全局登出
18 SP1服务器 1. 清除SP1本地会话(删除SP1的sessionid Cookie); 2. 重定向到IdP的全局登出接口:https://idp.company.com/logout?redirect_uri=https://company.com/logout_success 通知IdP执行全局登出
19 IdP服务器 1. 清除IdP全局会话(删除IdP的sessionid Cookie); 2. 遍历所有已登录的SP(IdP记录了用户登录过的SP列表),调用各SP的登出接口(如https://oa.company.com/logout、https://crm.company.com/logout) 终止全局会话,通知所有SP登出
20 所有SP服务器 接收到IdP的登出通知,清除各自的本地会话 同步退出所有系统
21 IdP服务器 重定向到统一的"登出成功"页面 完成全局登出

三、关键技术细节补充(避免流程漏洞)

  1. token的安全性保障 :
    • access_token必须用非对称加密(如RS256)签名:IdP用私钥签名,SP用公钥验证,防止token被篡改;
    • access_token有效期要短(1小时内),即使被盗,攻击窗口小;
    • refresh_token存储在IdP的HttpOnly Cookie中,禁止JS读取,防XSS攻击。
  2. 跨域场景的适配 :
    • 若IdP和SP域名不同(如idp.com和sp1.com),无法通过Cookie共享会话,可采用「OAuth2.0授权码模式」:IdP先返回code(授权码),SP再用code向IdP换取token,避免token暴露在URL中;
    • 或用「PostMessage」实现跨域通信,SP嵌入IdP的登录弹窗,登录成功后通过PostMessage传递token。
  3. 会话超时处理 :
    • IdP的全局会话设置超时时间(如2小时无操作),超时后自动失效,用户访问新SP时需重新登录;
    • SP的本地会话超时时间建议和IdP一致,避免SP会话有效但IdP会话失效的情况。

总结

  1. 核心逻辑:SSO的本质是「IdP统一管理身份认证,SP信任IdP颁发的token」,首次登录完成IdP全局会话创建,后续SP通过验证token实现免登;
  2. 关键步骤:首次登录的核心是"SP重定向→IdP认证→token回传→SP验证",免登的核心是"IdP识别全局会话→直接发token",登出的核心是"清除IdP全局会话+通知所有SP清本地会话";
  3. 安全关键:全程HTTPS、token短有效期+非对称签名、Cookie加HttpOnly/Secure/SameSite、state参数防CSRF。

关键点回顾:

  • SSO的核心是IdP的「全局会话」和给SP颁发的「token凭证」;
  • 免登的前提是IdP能识别用户的全局会话(通过Cookie中的sessionid);
  • 全局登出需同步清除IdP全局会话和所有SP的本地会话。
相关推荐
程序员大阳5 分钟前
副队长CSS教程(33)–圆角与透明
前端·css·透明·圆角
志尊宝16 分钟前
Vue3 零基础每日笔记(082):文件上传实战——el-upload 校验、自定义上传、头像预览
前端·javascript·vue.js·笔记·#javascript·#vue.js
鬼手点金41 分钟前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github
柳杉42 分钟前
借助 Codex 和可视化工作流,从调研到完整实现,3D 大屏竟然可以这么简单
前端·ai编程·数据可视化
IMPYLH1 小时前
HTML 的 <wbr> 元素
前端·html
Dovis(誓平步青云)2 小时前
常用命令藏得太深?怎么做一个快捷命令坞
运维·前端·自动化·音视频·prometheus
IT_陈寒2 小时前
Vite的这个问题坑了我三天,原来如此解决!
前端·人工智能·后端
网易云信2 小时前
大模型能上岗做销售吗?我们让 12 款国产模型交了 420 份作业
前端·后端
蜗牛互联网3 小时前
Python Agent工具调用的白名单、参数校验与审批门禁
java·服务器·前端·人工智能·后端·python
计算机魔术师3 小时前
Perplexity:每个 Project 都是一个 Git 仓库
前端