## 一、什么是单点登录 (SSO)?
单点登录 (Single Sign-On, SSO) 是一种身份验证方案,允许用户使用一组凭据(例如,用户名和密码)登录多个独立的软件系统或应用。用户只需进行一次身份验证,即可访问所有授权的关联应用,无需在每个应用中重复输入凭据。
**核心优势:**
* **提升用户体验:** 无需记忆和输入多套账号密码,简化登录流程。
* **增强安全性:** 减少密码疲劳和弱密码使用,集中管理用户凭证,便于实施更强的认证策略(如MFA)。
* **简化管理:** 集中管理用户账户和权限,降低IT管理成本。
* **提高生产力:** 用户可以更快地访问所需应用和服务。
## 二、SAML (Security Assertion Markup Language)
SAML是一种基于XML的开放标准,用于在不同的安全域之间交换身份验证和授权数据。它主要用于实现Web应用的单点登录。
**核心用途:** 在身份提供者 (IdP) 和服务提供者 (SP) 之间传递用户身份验证信息(称为"断言" Assertion)。
**关键参与方:**
* **主体 (Principal):** 通常指最终用户。
* **身份提供者 (Identity Provider, IdP):** 负责验证用户身份,并创建和发送SAML断言。例如,企业内部的Active Directory Federation Services (ADFS),Okta,Auth0等。
* **服务提供者 (Service Provider, SP):** 依赖IdP进行用户身份验证的应用或服务。例如,Salesforce, G Suite等。
**工作流程详解 (以SP发起为例):**
1. **用户访问SP:** 用户尝试访问服务提供者 (SP) 上的资源。
2. **SP重定向到IdP:** SP发现用户未认证,生成一个SAML身份验证请求 (SAML Request),并将用户的浏览器重定向到身份提供者 (IdP) 的SSO URL,并附带此请求。
3. **IdP验证用户:** IdP接收到请求,提示用户进行身份验证(例如,输入用户名密码,进行MFA)。如果用户已在IdP登录,则此步骤可能被跳过。
4. **IdP生成断言并发送给浏览器:** IdP验证用户成功后,会生成一个包含用户身份信息、授权信息和有效期的SAML断言 (SAML Assertion),该断言通常会进行数字签名以保证完整性和来源可信。IdP将此断言通过浏览器(通常以POST表单形式)发送回SP的断言消费服务 (Assertion Consumer Service, ACS) URL。
5. **浏览器将断言转发给SP:** 用户的浏览器自动将SAML断言提交给SP。
6. **SP验证断言并授权:** SP接收到SAML断言后,会验证其签名(使用IdP的公钥)、有效期、颁发者等信息。验证通过后,SP确认用户身份,并根据断言中的授权信息授予用户访问权限,建立本地会话。
**(IdP发起的流程也存在,即用户先登录IdP,然后从IdP的门户选择并访问SP)**
**典型应用场景:**
* 企业内部应用SSO(例如,员工登录公司门户后可直接访问CRM、HR系统等)。
* 跨组织的身份联合 (Federated Identity),允许一个组织的用户访问另一个组织的应用。
* 教育、政府等机构的Web应用SSO。
**优缺点分析:**
* **优点:**
* **成熟稳定:** 作为老牌标准,拥有广泛的行业支持和成熟的实现。
* **安全性高:** 支持XML签名和加密,提供较强的安全保障。
* **适用于Web浏览器SSO:** 专为基于浏览器的场景设计。
* **强大的联合身份能力:** 非常适合跨域身份管理。
* **缺点:**
* **XML的复杂性和冗余:** SAML消息基于XML,报文较大,解析复杂。
* **不适用于原生移动应用:** 对于非浏览器客户端(如移动App、桌面应用)支持不佳。
* **配置复杂:** IdP和SP之间的元数据交换和信任建立过程可能比较繁琐。
## 三、OAuth 2.0 (Open Authorization)
OAuth 2.0是一个开放的**授权框架**,它允许第三方应用在用户授权的情况下,获取用户在某一服务上特定资源的有限访问权限,而无需获取用户的凭据。
**核心用途:** **委托授权 (Delegated Authorization)**。它本身不是一个身份验证协议,尽管经常被误用或与身份验证方案结合使用。
**关键参与方:**
* **资源所有者 (Resource Owner, RO):** 通常是最终用户,能够授权访问其受保护的资源。
* **客户端 (Client):** 代表资源所有者请求访问受保护资源的第三方应用。
* **授权服务器 (Authorization Server, AS):** 负责验证资源所有者身份,并在获得授权后向客户端颁发访问令牌 (Access Token)。
* **资源服务器 (Resource Server, RS):** 托管受保护的资源,并接受和验证访问令牌,以允许客户端访问资源。
**核心授权流程 (以授权码模式 Authorization Code Grant 为例,这是最常用且推荐的模式):**
1. **客户端请求授权:** 客户端将资源所有者(用户)的浏览器重定向到授权服务器,并携带客户端ID、重定向URI、请求范围 (scope) 等参数。
2. **用户授权:** 授权服务器对资源所有者进行身份验证(如果尚未登录),并提示用户是否同意授权客户端访问其指定范围的资源。
3. **授权服务器返回授权码:** 如果用户同意授权,授权服务器会将用户的浏览器重定向回客户端预先注册的重定向URI,并附带一个一次性的授权码 (Authorization Code)。
4. **客户端用授权码交换访问令牌:** 客户端收到授权码后,通过其后端通道(保密)向授权服务器的令牌端点 (Token Endpoint) 发送请求,使用授权码、客户端ID和客户端密钥来交换访问令牌 (Access Token) 和可选的刷新令牌 (Refresh Token)。
5. **客户端使用访问令牌访问资源:** 客户端使用获取到的访问令牌,向资源服务器请求受保护的资源。资源服务器验证访问令牌的有效性(例如,签名、有效期、范围),如果有效则返回资源。
**其他常见授权模式:**
* **隐式授权模式 (Implicit Grant):** 简化流程,直接返回访问令牌,适用于无法安全存储客户端密钥的纯前端应用(安全性较低,已不推荐)。
* **资源所有者密码凭据模式 (Resource Owner Password Credentials Grant):** 客户端直接使用用户的凭据向授权服务器获取访问令牌,仅适用于高度信任的客户端(例如,操作系统自身或第一方应用)。
* **客户端凭据模式 (Client Credentials Grant):** 用于机器到机器的授权,客户端以自身名义请求访问受保护资源,不涉及最终用户。
**典型应用场景:**
* 第三方应用集成(例如,"使用Google/Facebook/微信账号登录"并授权访问部分信息)。
* API授权管理(保护Web API,只允许授权的客户端访问)。
* 移动应用访问后端服务。
* 微服务架构中服务间的授权。
**优缺点分析:**
* **优点:**
* **灵活性高:** 提供多种授权模式,适应不同场景。
* **广泛采用:** 是现代应用授权的事实标准。
* **适用于多种客户端:** 良好支持Web应用、移动应用、桌面应用和API。
* **基于JSON和HTTP:** 相较于SAML更轻量,易于使用。
* **缺点:**
* **本身不处理身份验证:** OAuth 2.0 关注授权,不直接提供用户身份信息。需要结合其他机制(如OIDC)来实现完整的SSO。
* **安全性依赖实现:** 规范本身留有很多选择,不当的实现可能导致安全漏洞(例如,令牌泄露)。
* **"熊孩子"问题 (Bearer Token):** 访问令牌通常是Bearer Token,意味着持有者即可使用,因此必须通过HTTPS传输并妥善保管。
## 四、OIDC (OpenID Connect)
OIDC (OpenID Connect) 是一个构建在 OAuth 2.0 协议之上的简单身份层 (Identity Layer)。它允许客户端基于授权服务器执行的身份验证来验证最终用户的身份,并以可互操作和类似REST的方式获取用户的基本身份信息。
**核心用途:** 在OAuth 2.0的授权流程基础上,提供用户**身份验证**,并标准化身份信息的获取。
**关键参与方 (与OAuth 2.0类似,但有特定称谓和新增元素):**
* **最终用户 (End-User):** 即资源所有者。
* **依赖方 (Relying Party, RP):** 即OAuth 2.0中的客户端,它依赖OIDC提供者进行用户身份验证。
* **OpenID提供者 (OpenID Provider, OP):** 即OAuth 2.0中的授权服务器,但增加了身份验证服务和颁发ID Token的功能。
* **(资源服务器依然存在,用于访问令牌访问受保护API)**
**新增核心元素:**
* **ID Token:** 一个JSON Web Token (JWT),包含了关于身份验证事件和用户的声明 (Claims)。这是OIDC的核心,用于向RP证明用户身份。
* **UserInfo端点 (UserInfo Endpoint):** 一个受OAuth 2.0保护的资源服务器API,RP可以使用访问令牌从该端点获取更多关于用户的声明信息。
**工作流程详解 (通常基于OAuth 2.0的授权码流程):**
1. **RP向OP发起认证请求:** RP将用户的浏览器重定向到OP,请求中包含`openid` scope,以及可能的其他scopes(如`profile`, `email`)。
2. **用户在OP进行身份验证和授权:** 用户在OP登录并同意RP的请求。
3. **OP返回授权码给RP:** OP将用户的浏览器重定向回RP的重定向URI,并附带授权码。
4. **RP用授权码交换令牌:** RP通过后端通道向OP的Token端点发送请求,使用授权码交换 **ID Token** 和 **Access Token** (以及可选的Refresh Token)。
5. **RP验证ID Token并获取用户信息:**
* RP必须严格验证ID Token的签名、颁发者 (iss)、受众 (aud)、有效期 (exp, iat)、nonce等声明,以确认用户身份。
* ID Token本身包含了一些基本的用户信息(如`sub`用户唯一标识符, `iss`, `aud`, `exp`, `iat`等)。
6. **(可选) RP使用Access Token访问UserInfo端点:** 如果需要更多用户信息(且用户已授权相应scopes),RP可以使用Access Token向OP的UserInfo端点请求更多声明。
7. **RP建立用户会话:** 验证成功后,RP为用户建立本地会话。
**典型应用场景:**
* 现代Web应用和移动应用的SSO(例如,替代SAML成为新的主流)。
* 社交登录("使用Google/Facebook/Apple账号登录")。
* API驱动的应用需要用户身份验证。
**优缺点分析:**
* **优点:**
* **基于OAuth 2.0:** 继承了OAuth 2.0的灵活性和广泛支持。
* **提供标准身份层:** 解决了OAuth 2.0本身不直接提供身份验证信息的问题。
* **使用JWT:** ID Token采用JWT格式,轻量、易于解析和验证。
* **适用于现代架构:** 非常适合移动优先、API驱动的架构。
* **安全性:** 提供了明确的ID Token验证机制和nonce等防重放攻击手段。
* **缺点:**
* **相对复杂:** 同时涉及OAuth 2.0和OIDC本身的规范,理解和实现仍有一定复杂度。
* **依赖于OAuth 2.0的正确实现:** OAuth 2.0流程中的安全问题同样会影响OIDC。
## 五、SAML vs OAuth 2.0 vs OIDC:对比与选择
| 特性 | SAML | OAuth 2.0 | OIDC (OpenID Connect) |
|--------------|----------------------------------------|-----------------------------------------|-----------------------------------------|
| **核心目标** | Web浏览器SSO,身份联合 | 委托授权 (API访问控制) | 用户身份验证 (基于OAuth 2.0) |
| **主要载体** | XML断言 (Assertion) | 访问令牌 (Access Token) | ID Token (JWT), Access Token |
| **身份验证** | 是 (IdP负责) | 否 (本身不处理,由AS可能执行) | 是 (OP负责,提供ID Token) |
| **授权** | 是 (断言中可包含授权信息) | 是 (核心功能,通过Scope和Token) | 是 (通过OAuth 2.0的Access Token和Scope) |
| **数据格式** | XML | JSON (令牌格式不限,但常为JWT或不透明字符串) | JWT (ID Token), JSON (UserInfo) |
| **复杂度** | 较高 (XML, WS-\* 规范) | 中等 (多种授权模式) | 中高 (构建于OAuth 2.0之上) |
| **适用场景** | 企业级SSO, B2B联合身份 | API授权, 第三方应用访问, 移动应用授权 | 现代Web/移动应用SSO, 社交登录 |
| **移动/API友好**| 较差 | 良好 | 非常好 |
**何时选择哪个协议?**
* **选择 SAML 如果:**
* 主要场景是传统的Web浏览器单点登录,尤其是在企业内部或B2B的联合身份场景中。
* 需要与大量已支持SAML的老旧系统集成。
* 对XML生态系统有深厚投入。
* **选择 OAuth 2.0 如果:**
* 核心需求是**授权**,即允许第三方应用访问用户在服务上的数据,而不是完整的用户身份验证。
* 构建API,并需要控制哪些客户端可以访问这些API以及它们能做什么。
* 开发移动应用,需要安全地访问后端资源。
* **选择 OIDC 如果:**
* 你需要一个完整的**身份验证和授权**解决方案,尤其适用于现代Web应用和移动应用。
* 希望在OAuth 2.0的授权流程之上,方便地获取和验证用户身份信息。
* 正在构建新的SSO系统,OIDC通常是更现代和推荐的选择。
* 需要实现"社交登录"功能。
**重要提示:** OAuth 2.0 和 OIDC 经常一起使用。OIDC利用OAuth 2.0的流程来颁发ID Token(用于身份验证)和Access Token(用于访问受保护资源,如UserInfo端点或其他API)。
## 六、总结
SAML、OAuth 2.0和OIDC是实现单点登录和安全授权的关键协议,它们各自有不同的设计目标和适用场景。SAML是成熟的企业级Web SSO解决方案;OAuth 2.0专注于委托授权,是API经济的基石;而OIDC则在OAuth 2.0之上提供了一个现代的身份层,成为当前Web和移动应用SSO的主流选择。理解它们的核心机制和差异,有助于在构建安全、便捷的身份验证和授权系统时做出正确的技术选型。