概述
当你在公司的内部系统上来回切换而不需要密码登录时,当你任意系统的登录态过期,跳转的授权页面都是统一的页面时,明明是不同的厂商给公司开发售卖的系统,但是却能够通过一个账号实现互联互通,你有没有想过,这背后,是什么驱动着这种链接?
答案就是本文所要说的 Single-Sign-On,单点登录,即我们常说的 SSO 登录。
传统认证体系
传统认证体系就是一个系统使用一套账号密码,在用户登录的时候通过对应系统的账号密码访问,但是当 有多个系统时,用户需要记住每一个系统的账密,存在心智负担,而用户为了记忆方便,选择共同使用一套账密,使得安全风险提升,当一个系统被破解后,就会引发多米诺骨牌效应,所有的系统都可以被快速破解。
此外,账密系统本身也很复杂,无论是初始开发还是后续升级,都需要投入大量的人力成本为每一个系统进行升级,再加上各系统之间的身份、角色、权限点的设置不同,难度也是不一样的。
所以为了解决这个困境,后来才提出了 SSO。
SSO 核心体系
什么是 SSO
单点登录(Single Sign-On,SSO)是为了解决跨系统身份认证的问题应运而生的,用户只需要一次认证,即可无缝访问所有相互信任的应用系统。
SSO 核心是:
- 中央认证服务(Central Authentication Service,CAS):由可信的认证中心统一进行登录认证。
- 票据机制:使用安全令牌(Ticket/Token)代替密码传递。
- 会话代理:各个系统信任 CAS 颁发的凭证,而不需要重复的验证密码。
在了解 SSO 之前,你需要掌握一些关键术语:
| 术语 | 职责 | 示例 |
|---|---|---|
| IdP (Identity Provider) | 身份提供者,负责认证用户 | Azure AD, Okta, Auth0 |
| SP (Service Provider) | 服务提供者,依赖IdP的身份断言 | GitLab, Jira, 自研业务系统 |
| SAML | 基于XML的认证协议,企业级应用主流 | 企业内网系统集成 |
| OAuth 2.0 | 授权框架,常用于API访问控制 | 第三方登录、开放平台 |
| OIDC (OpenID Connect) | 基于OAuth 2.0的身份层,现代SSO首选 | 云原生应用、移动端 |
| TGT (Ticket Granting Ticket) | 建立全局会话的凭证,包含用户信息、票据生命周期等信息。 | |
| TGC (Ticket Granting Cookie) | 认证服务器认证成功后返回给浏览器的 cookie,与存储在认证服务器上的 TGT 相对应,TGC 和 TGT 类似于 cookie 和 session 的关系。 | |
| ST (Service Ticket) | 服务凭证,用于客户端验证用户身份 |
工作原理
一个经典的 CAS 流程图(以 OAuth 2.0 为例)以及关键步骤描述:
sequenceDiagram
participant 用户浏览器
participant SP(应用服务)
participant IdP(认证中心)
用户浏览器->>SP(应用服务): 1. 访问应用(无会话)
SP(应用服务)->>用户浏览器: 2. 重定向到IdP授权端点
用户浏览器->>IdP(认证中心): 3. 进入登录页,认证用户身份
IdP(认证中心)->>用户浏览器: 4. 返回授权码,重定向回SP
用户浏览器->>SP(应用服务): 5. 携带授权码请求回调
SP(应用服务)->>IdP(认证中心): 6. 用授权码换取访问令牌
IdP(认证中心)->>SP(应用服务): 7. 返回ID Token和Access Token
SP(应用服务)->>SP(应用服务): 8. 验证令牌,创建局部会话
SP(应用服务)->>用户浏览器: 9. 返回应用页面,正常访问
- 未登录态访问:用户访问SP,SP检查无有效会话,将用户重定向至IdP授权端点
- 授权请求:SP携带
client_id、redirect_uri、response_type=code、scope等参数请求授权 - 身份验证:IdP验证用户身份(若未登录则展示登录页),用户同意授权
- 授权码发放:IdP生成一次性授权码(Authorization Code),通过浏览器重定向回SP回调地址
- 换取令牌:SP使用授权码、客户端密钥向IdP令牌端点发起POST请求
- 令牌颁发:IdP验证授权码后,颁发ID Token(身份令牌)和Access Token(访问令牌)
- 会话建立:SP验证ID Token签名与声明,解析用户信息,创建局部会话(如设置Cookie)
- 后续访问:其他SP重复此流程,但因用户已在IdP建立会话,无需再次输入密码,实现SSO
上述这一系列优雅连贯的步骤背后还隐藏着一个核心的技术问题:HTTP 协议是无状态的,而 SSO 又是需要持续追踪用户认证状态的,那么我们要在哪里去保存这个状态实现持续的追踪呢?
SSO 对于状态的保存和共享,采取的解法就是中央会话存储和安全令牌传递机制,通过三层架构实现认证流程的状态稳定:
- 浏览器层:通过 Cookie 或者 Storage 存储客户端状态
- 网络层:通过重定向、POST 请求传递一次性授权码
- 服务器层:中央 IdP 维护全局会话,各个 SP 维护自身的局部会话
主流协议
业界实现的主流核心协议主要有以下几种:
-
CAS:Central Authentication Service,是一种基于票据的验证机制
-
核心流程:
- 首次访问:用户首次访问 SP 时被重定向到 CAS 服务器登录,在登录成功后,CAS 生成 TGT(Ticket Granting Ticket) 存入 Cookie 中。
- 票据派发:CAS 根据 TGT 签发一次性的 ST(Service Ticket),通过回调地址返回给应用。而 SP 利用 ST 向 CAS 服务器验证身份,验证通过后,建立局部会话。
- 后续访问:用户访问其他应用时,浏览器将 TGT 携带在请求中,同步发送给 CAS 服务器,快速完成 ST 的换取,实现免登录。
-
特点:流程清晰简洁,适合于内部系统
-
-
OAuth2.0/OIDC:基于授权码和 JWT 令牌的认证
-
核心流程:
- 首次访问:用户首次访问 SP 时,重定向到授权服务器,登录成功后,此时返回授权码,而非令牌。授权码是一次性的。
- 令牌交换:应用 SP 用授权码向授权服务器换取 Access Token(访问令牌) 、 ID Token(身份令牌,JWT 格式)、Refresh Token(刷新令牌),这三者会打包返回。
- 身份验证:应用通过 ID Token 获取用户信息并建立会话,Access Token 用来调用资源服务器 API,Refresh Token 在后台静默续期,是一次性的,即,每次续期后失效,同时获取新的 Refresh Token。
-
特点:基于 Token 机制,是无状态的,天然的支持跨域、移动端等场景。互联网应用首选方案。
-
-
SAML2.0:Security Assertion Markup Language 2.0,是基于 XML 断言的认证。
-
核心流程:
- 首次访问:首次访问 SP 时,SP 生成 SAML 认证请求,该请求为 XML 格式,包含了签发者、回调地址等信息,通过浏览器重定向到 IdP。
- 身份验证:用户在 IdP 登录后,IdP 生成 SAML 响应,包含断言、数字签名、使用条件等信息,通过 POST 方式回调 SP。
- 断言认证:SP 响应 IdP 回调的信息后,提取用户信息并建立局部会话。
- 后续访问:用户访问其他 SP 时,浏览器会携带 IdP 持久化的 Cookie 信息(协议规范中没有明确这一要求,这是由 IdP 服务自行选择的),在 IdP 服务直接重新生成新的断言并完成登录。
-
特点:基于 XML 数字签名,复杂度和安全性很高,但是不够轻量,一般用于金融、政务等场景。
-
SAML2.0 存在一个绑定机制,主要有三种实现方式:
- HTTP-Redirect:SAMLRequest 通过 URL 参数 GET 传递,适合短请求
- HTTP-POST:通过表单 POST 传递,无大小限制,安全性更高
- Artifact:仅传递 artifact ID,SP 后台通过 SOAP 回调获取真实断言,最安全
-
sequenceDiagram
participant 用户 as 用户浏览器
participant SP as 应用服务(SP)
participant IdP as 身份提供者(IdP)
用户->>SP: 访问受保护资源
SP->>用户: 生成 SAML Request 并重定向至 IdP
用户->>IdP: GET 携带 SAML Request
Note over IdP: 检查无全局会话
IdP->>用户: 返回登录页面
用户->>IdP: 提交用户名密码
IdP->>IdP: 生成 SAML Response(含断言)
IdP->>用户: POST SAML Response 至 SP ACS地址
用户->>SP: 携带 SAML Response
Note over SP: 验签、验证断言、创建局部会话
SP->>用户: 设置 SP Cookie,返回资源
Note over 用户,IdP: IdP 同时写入持久化 Cookie (TGC)
用户->>SP: 访问另一SP应用
SP->>用户: 生成 SAML Request 重定向至 IdP
用户->>IdP: GET 携带 SAML Request
Note over IdP: 存在全局会话(TGC),直接生成断言
IdP->>用户: POST 新 SAML Response 至SP
用户->>SP: 携带 SAML Response
Note over SP: 验签后创建会话
SP->>用户: 返回资源(无需再次登录)
实现方案
这里列举几个目前行业通用的 SSO 架构实现方案,以作为了解
基于 Cookie 的 SSO
这种方案是利用了浏览器的 Cookie 在同域下自动携带发送的特性,基于这个特性,我们将用户的登录态保存在服务端的 Session 中,Cookie 中保存的是 SessionID,在客户端与不同服务交互过程中,传递该 ID 给服务器用于判断。
典型应用:CAS 协议、同域 SSO 架构。
基于 Token 的 SSO
目前行业中使用最频繁的 SSO 方案,采用无状态的 JWT 令牌,由 IdP 签名提供给前端,在该令牌内同时包含了用户的身份和权限,存储在客户端的 storage 中,在后续前端和服务交互的过程中,前端每次发起请求时,都会自动的将 JWT 注入到请求头中(业务自行协商存放位置),在 SP 服务中,直接验证签名就可以确认身份,不需要实时的请求 IdP。
典型应用:OAuth 2.0,OIDC,跨域 SSO 架构。
安全防护
SSO 落地过程中,除了协议的实现外,还要面对着不少安全问题,因为 SSO 的设计上是“一次登录,全域通行”,所以如果 SSO 被攻破,就会引发全域风险,所以在 SSO 落地的时候,还需要建立多层的防护。
-
凭证泄露
- 场景:XSS 窃取 Cookie/localStorage 中的 JWT;中间人劫持未加密的 Cookie
- 应对:相关 SSO Cookie 禁止使用 JS 访问(Cookie 策略为
HttpOnly + Secure + SameSite);localStorage 中存放的 JWT 配合 CSP 策略防护;强制 HTTPS 协议,避免中间人劫持;缩短令牌有效期,避免泄露后损失扩大。
-
CSRF 攻击
- 场景:恶意网站利用用户浏览器中的有效 Cookie 发起登录、登出请求
- 应对:关键请求增加 CSRF 令牌,确保请求来源合法;请求来源(Origin/Referer)增加白名单校验;禁止 Cookie 跨域携带。
-
凭证伪造与重放
- 场景:伪造 JWT Payload 越权;劫持 CAS 票据重复登录
- 应对:严格进行签名验证;凭证(ST、授权码)失效策略配置有效期、使用次数;账号异常检测
SSO 未来
SSO 诞生(以 SAML1.0 标准发布时间计算)至今,已有 24 个年头了,这么多年的演进,让 SSO 成为了企业和互联网平台的身份管理基础设施之一,而随着标准的不断丰富完善,以及身份管理场景的不断扩展,SSO 正朝着更加安全、便捷、智能的方向进行演进。
在安全性层面,无密码认证(FIDO2/WebAuthn)正在从根本上消除密码泄露风险,AI 驱动的自适应认证则能实时分析用户行为,动态调整认证强度,精准识别并阻断异常登录。同时,SSO 与零信任架构的深度融合,将身份验证从"一次性登录"扩展为"持续验证",每次资源访问均需重新评估身份与上下文,构建动态信任边界。
在便捷性与隐私层面,去中心化身份(SSI)赋予用户数据主权,身份凭证由用户自持而非集中托管,既提升隐私保护,又打破组织间身份孤岛。
综合看来,SSO 已经从原来简单的单点登录服务进化成为智能身份中枢,相信未来在无密码、AI 增强、去中心化这三大需求的驱动下,走向一次认证,全球通行的大一统时代。