4、单点登录(SSO)与联合身份:SSO工作原理、SAML与OAuth 2.0协议、LDAP与Active Directory集成
聊到企业安全,有个话题几乎绕不开——单点登录。说白了,就是让用户只登一次,就能访问所有系统。我早年在一家电商公司做架构时,光维护密码就快疯了:ERP一套密码,CRM一套,BI报表又一套。员工每天花在找回密码上的时间,比干活还多。
后来我们上了SSO。效果立竿见影。但坑也不少。今天我把这些经验掰开揉碎,跟你聊聊。
4.1 SSO的核心逻辑:一次认证,到处通行
SSO的原理其实不复杂。你想想看,用户登录后,系统发一个“通行证”。这个通行证被所有应用信任。用户再访问其他系统时,拿着通行证晃一下就行。
这个通行证,通常是个令牌(Token)。它存储在浏览器Cookie里,或者通过重定向传递。
SSO的核心三要素:
- 认证中心(IdP):负责验证用户身份,签发令牌
- 服务提供者(SP):实际提供业务功能的系统
- 令牌(Token):证明用户已登录的凭证
我在项目中遇到过一种情况:开发团队自己写了个SSO,用Session共享。结果用户量一上来,Session风暴直接把数据库打挂了。嗯,这里要注意——SSO不是简单的Session复制,它需要专门的协议支撑。
4.2 SAML协议:企业级的老大哥
SAML(Security Assertion Markup Language)是SSO领域的老牌协议。它基于XML,主要用在企业级场景。
SAML的工作流程,我习惯用“介绍信”来理解:
- 用户访问SP(比如企业OA)
- SP发现用户没登录,把用户踢到IdP(认证中心)
- 用户在IdP输入密码,IdP验证通过后,生成一个SAML断言
- IdP把这个断言通过浏览器重定向发给SP
- SP解析断言,确认用户身份,允许访问
这个断言里包含什么?用户ID、属性、权限、有效期。SP拿到后,直接信任。
我的经验:SAML的XML解析是个性能瓶颈。我曾经在一个高并发场景下,SAML断言解析耗时超过200ms。后来我们加了缓存,把解析结果缓存起来,才压下去。
SAML有两种绑定方式:
| 绑定方式 | 传输方式 | 适用场景 |
|---|---|---|
| HTTP Redirect | URL参数传递 | 简单、快速,但长度受限 |
| HTTP POST | 表单提交 | 支持大数据量,更安全 |
我个人更推荐POST方式。为什么?因为Redirect方式会把断言暴露在URL里,容易被日志记录。安全审计时,这就是个风险点。
4.3 OAuth 2.0:现代应用的通行证
如果说SAML是企业级的老大哥,那OAuth 2.0就是互联网应用的当红炸子鸡。它最初是为授权设计的,但后来被广泛用于认证。
OAuth 2.0有四种授权模式:
| 模式 | 适用场景 | 安全等级 |
|---|---|---|
| 授权码模式 | Web应用、移动App | 高 |
| 隐式模式 | 纯前端应用(已不推荐) | 中 |
| 密码模式 | 受信任的内部应用 | 低 |
| 客户端凭证模式 | 服务间调用 | 高 |
我最常用的是授权码模式。流程大概是:
- 用户点击“用登录”
- 应用把用户重定向到认证页
- 用户确认授权
- 返回一个授权码
- 应用用授权码去后端换Access Token
- 应用拿着Token获取用户信息
避坑指南:我曾经见过一个团队,把Access Token直接存在前端LocalStorage里。结果XSS攻击一打,Token全被偷了。正确的做法是存在HttpOnly Cookie里,或者用PKCE增强安全。
SAML和OAuth 2.0怎么选?我个人的判断标准:
- 如果对接的是传统企业系统(如SAP、Oracle),选SAML
- 如果对接的是互联网应用(如、Google),选OAuth 2.0
- 如果两者都要,用OpenID Connect(OAuth 2.0的认证扩展)
4.4 LDAP与Active Directory:目录服务的基石
聊完协议,我们看看底层存储。LDAP(轻量级目录访问协议)和Active Directory(AD)是企业里最常见的身份存储方案。
LDAP是个协议,AD是微软对LDAP的实现。你可以把LDAP想象成一个电话本,专门存用户、组、权限这些信息。查询速度极快,但写入性能一般。
AD在企业里几乎是标配。它不光存用户,还管策略、证书、DNS。我见过最夸张的AD,存了10万个用户,查询响应还在10ms以内。
SSO和LDAP/AD的集成,通常有两种方式:
- 直接认证:应用直接连LDAP验证密码。简单,但每个应用都要配一遍。
- 通过IdP代理:IdP连LDAP,应用只信任IdP。这是SSO的标准做法。
我建议用第二种。为什么?因为密码策略、账号锁定、审计日志,都可以在IdP统一管理。你想想看,如果每个应用都直接连AD,改个密码策略得改多少个系统?
LDAP集成时的关键配置:
- Base DN:搜索的根节点,比如 dc=example,dc=com
- Bind DN:连接LDAP的服务账号
- Filter:用户搜索条件,比如 (uid={username})
- Attribute Mapping:LDAP属性到应用字段的映射
我曾经在一个项目中,LDAP的Base DN配错了。结果用户搜索时,返回了全公司的账号。嗯,这是个严重的安全事故。从那以后,我每次配LDAP都会先跑一条搜索命令验证:
ldapsearch -x -H ldap://ad.example.com -b "ou=users,dc=example,dc=com" "(uid=testuser)"
确认只返回目标用户,再上线。
4.5 一张图看懂SSO生态
说了这么多,我们画张图把整个SSO生态串起来。
4.6 联合身份:跨组织的信任
SSO解决的是企业内部的问题。那如果我要和合作伙伴的系统对接呢?这就轮到联合身份(Federation)出场了。
联合身份的核心是信任。企业A的IdP信任企业B的IdP。用户在企业B登录后,可以直接访问企业A的资源。
实现方式有两种:
- SAML Federation:通过元数据交换建立信任。每个企业发布自己的元数据,对方导入即可。
- OpenID Connect:基于OAuth 2.0,通过Discovery URL动态发现IdP信息。
我在做跨国项目时,遇到过时区问题。SAML断言里的时间戳是UTC,但SP的服务器时区配错了。结果断言被当成过期,用户死活登不上。排查了整整一天。从那以后,我要求所有系统统一用UTC时间。
我的建议:做联合身份时,先建一个测试环境。两边IdP先联调,确认断言能正常解析,再上生产。别问我为什么知道——我吃过亏。
4.7 安全注意事项
SSO虽然方便,但风险也集中了。一旦IdP被攻破,所有系统都失守。所以,安全措施必须到位:
| 风险点 | 应对措施 |
|---|---|
| IdP单点故障 | 部署多节点,做负载均衡 |
| 令牌泄露 | 使用HTTPS,令牌设置短有效期 |
| CSRF攻击 | 使用State参数,验证来源 |
| 重放攻击 | 加入Nonce和时间戳校验 |
| LDAP注入 | 对输入做转义,使用参数化查询 |
嗯,最后说一句。SSO不是银弹。小团队用简单的Session共享可能更合适。但一旦超过三个系统,或者有外部合作需求,SSO就是必选项。选对协议,配好安全,你的企业身份体系就能稳稳跑起来。