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的工作流程,我习惯用“介绍信”来理解:

  1. 用户访问SP(比如企业OA)
  2. SP发现用户没登录,把用户踢到IdP(认证中心)
  3. 用户在IdP输入密码,IdP验证通过后,生成一个SAML断言
  4. IdP把这个断言通过浏览器重定向发给SP
  5. 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 高
隐式模式 纯前端应用(已不推荐) 中
密码模式 受信任的内部应用 低
客户端凭证模式 服务间调用 高

我最常用的是授权码模式。流程大概是:

  1. 用户点击“用登录”
  2. 应用把用户重定向到认证页
  3. 用户确认授权
  4. 返回一个授权码
  5. 应用用授权码去后端换Access Token
  6. 应用拿着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的集成,通常有两种方式:

  1. 直接认证:应用直接连LDAP验证密码。简单,但每个应用都要配一遍。
  2. 通过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生态串起来。

SSO与联合身份架构图 用户 浏览器 身份提供者(IdP) 服务提供者(SP) LDAP / Active Directory 令牌缓存/数据库 核心流程说明: 1. 用户通过浏览器访问SP,SP检查是否有有效令牌 2. 无令牌时,SP将用户重定向到IdP进行认证 3. IdP验证用户身份(可对接LDAP/AD),签发SAML断言或OAuth令牌 4. 用户携带令牌访问SP,SP验证令牌后允许访问 5. 令牌可缓存,后续访问无需重复认证

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就是必选项。选对协议,配好安全,你的企业身份体系就能稳稳跑起来。