要解决什么问题
一个组织内部有几十个系统:邮箱、OA、CRM、代码仓库……
如果每个系统都要单独注册和登录,体验糟糕,且密码管理困难(容易导致重复使用弱密码)。
SSO(Single Sign-On,单点登录):登录一次,即可访问所有互信的系统。
基本架构
身份提供方(IdP):负责认证用户,存储身份信息。
服务提供方(SP):各个业务系统,信任 IdP 的认证结果。
流程:
- 用户访问 SP;
- SP 发现用户未登录,重定向到 IdP;
- 用户在 IdP 登录(如果已在 IdP 登录过,这步跳过);
- IdP 生成一个认证断言(Token),重定向回 SP;
- SP 验证断言的签名,确认用户身份,建立本地会话。
常见协议
SAML
基于 XML 的协议,在企业 SSO 中应用广泛(尤其大型企业的内部系统)。
特点:成熟、功能完整(支持丰富的属性传递),但 XML 冗长、实现复杂。
OIDC(OpenID Connect)
建立在 OAuth 2.0 之上的身份认证层,使用 JWT(JSON Web Token) 传递身份信息。
特点:JSON 格式、轻量、对 Web 和移动端友好。是当前互联网应用的主流选择。
OAuth 2.0 到底是做什么的
一个关键区分:OAuth 2.0 是授权(Authorization)框架,不是认证(Authentication)协议。
它解决的场景是:让第三方应用在用户许可下访问用户的资源,而不必拿到用户的密码。
举例:你用"微信登录"某个 App,并同意它获取你的昵称和头像。
- 这个 App 拿到的是一个访问令牌(Access Token),用于调用微信 API 获取你的资料;
- 它没有拿到你的微信密码。
OIDC 在此基础上增加了认证层:通过 ID Token(JWT 格式)明确传递"这个用户是谁、什么时候登录的",从而可以用于身份认证。
OAuth 2.0 的主要流程
授权码模式(Authorization Code Flow)——最常用、最安全:
- 应用把用户重定向到授权服务器;
- 用户登录并同意授权;
- 授权服务器把用户重定向回应用,带上一个一次性授权码;
- 应用在后端(用 client secret)用授权码换取 Access Token。
为什么令牌不直接返回给前端:因为前端(浏览器/App)是不安全环境,令牌可能被截获。
授权码模式把令牌交换放在后端进行,且需要 client secret —— 这是安全的关键。
PKCE(Proof Key for Code Exchange):为公共客户端(移动 App、SPA)设计的扩展。它用一个临时的密钥对来防止授权码被拦截后冒用。
现代实践中,即使是 Web 应用也推荐启用 PKCE。
安全要点
- 令牌要有过期时间,且访问令牌应尽量短(配合刷新令牌使用);
- 校验 JWT 签名,不要相信未验证的令牌内容;
- 校验受众(aud)和签发者(iss):防止令牌被用在错误的服务上;
- 使用 HTTPS:令牌在网络上传输必须加密;
- 正确处理登出:SSO 的登出要通知 IdP 和各 SP,否则只是"看起来登出了"。
一个常见误解
"用了 OAuth 就安全了。"
OAuth 只规范了授权流程,具体的安全性取决于实现。错误的实现(如不校验 state 参数导致 CSRF、令牌存储不当、使用不安全的重定向)依然是漏洞来源。
说明:本文为身份认证与授权的知识整理。