SAML 2.0 (Security Assertion Markup Language) 详解
SAML (Security Assertion Markup Language) 2.0 是一种基于 XML 的开放标准,用于在不同的安全域之间交换身份验证和授权数据。其核心目标是实现企业级单点登录 (Single Sign-On, SSO),允许用户在一个系统中认证后,无需再次输入凭据即可访问多个关联服务。SAML 2.0 于 2005 年 3 月被 OASIS 批准为标准,整合了 SAML 1.1、Liberty ID-FF 1.2 和 Shibboleth 1.3 的优点,成为企业联合身份管理领域的主流协议。
核心思想:
- SSO(单点登录):用户只需登录一次,即可访问多个应用程序。
- 身份联合 (Identity Federation):在不同安全域之间共享用户身份信息和访问权限。
- 基于 XML:所有交换的消息(如认证请求、响应和断言)都采用 XML 格式。
- 信任关系: IdP 和 SP 之间需要预先建立信任关系,通常通过交换元数据实现。
- 解耦:将身份认证与服务提供解耦,提高安全性并降低管理成本。
一、为什么需要 SAML 2.0?传统认证的局限性
在没有 SSO 的环境中,用户需要为每个应用程序维护一套独立的账号和密码。这导致了一系列问题:
- 用户体验差:用户需要记忆并输入多套凭据,效率低下。
- 密码疲劳及安全隐患:用户可能重复使用弱密码,或者将密码写下来,增加被盗用的风险。
- 管理复杂:企业 IT 部门需要管理多个用户目录和认证系统,成本高昂且容易出错。
- 跨域访问困难:在不同公司或组织之间共享资源和身份变得非常复杂。
SAML 2.0 通过引入单点登录 (SSO) 和身份联合 (Identity Federation) 的概念,有效解决了这些问题。它允许用户在主身份提供者处一次性登录,然后安全地访问所有信任该身份提供者的服务,而无需重复认证。
二、SAML 2.0 的核心概念
SAML 2.0 认证过程涉及几个关键角色和组件:
2.1 参与方 (Actors)
- 用户 (Principal):尝试访问受保护资源或服务的最终用户。 通常通过 Web 浏览器(用户代理)与 IdP 和 SP 互动。
- 身份提供者 (Identity Provider, IdP): 负责认证用户并发布关于用户身份和认证状态的 SAML 断言。 常见的 IdP 包括 Okta、Azure AD、ADFS、OneLogin 等。
- 职责:
- 认证用户(密码、MFA 等)。
- 维护用户目录/属性。
- 生成并签署 SAML 断言。
- 处理来自 SP 的 SSO 请求。
- 管理单点注销。
- 职责:
- 服务提供者 (Service Provider, SP): 提供受保护资源或服务的应用程序。 它依赖 IdP 提供的 SAML 断言来验证用户身份和授权。 常见的 SP 包括 Salesforce、Google Workspace、Webex、ADP 等。
- 职责:
- 生成认证请求 (
SAMLRequest)。 - 接收并验证 SAML 响应。
- 验证断言上的数字签名。
- 从断言中提取用户身份。
- 为认证用户创建本地会话。
- 生成认证请求 (
- 职责:
2.2 断言 (Assertions)
SAML 断言 (SAML Assertion) 是一个 XML 文档,由 IdP 发出,包含关于用户身份、认证状态和可选授权属性的信息。 它是 IdP 向 SP 传递信任信息的载体。
SAML 2.0 定义了三种主要类型的断言语句:
AuthnStatement(认证语句):声明用户已通过何种方式在何时被 IdP 认证。 提供用户身份的确认。AttributeStatement(属性语句):包含用户的附加属性,如姓名、电子邮件、角色、部门等。 SP 可以使用这些属性进行授权决策和个性化服务。AuthzDecisionStatement(授权决策语句):声明 IdP 对用户是否被授权访问特定资源或执行特定操作的决定。
2.3 协议 (Protocols)
SAML 协议定义了参与方如何交换 SAML 消息,例如 AuthnRequest (认证请求) 和 Response (响应)。
2.4 绑定 (Bindings)
SAML 绑定 (SAML Bindings) 定义了 SAML 协议消息如何传输到基础通信协议(如 HTTP)上。 SAML 2.0 常见绑定包括:
- HTTP Redirect Binding:通过 HTTP GET 请求的查询参数在 URL 中传输 SAML 消息。
- HTTP POST Binding:通过 HTTP POST 请求的表单数据在请求体中传输 SAML 消息。
- HTTP Artifact Binding:不直接传输 SAML 消息,而是传输一个 “Artifact”(令牌),SP 凭此 Artifact 再向 IdP 请求实际的 SAML 消息。
2.5 配置文件 (Profiles)
SAML 配置文件 (SAML Profiles) 结合了特定用例的 SAML 断言、协议和绑定,以实现特定的功能,例如:
- Web 浏览器 SSO 配置文件 (Web Browser SSO Profile):最常用的配置文件,用于在 Web 浏览器环境中实现单点登录。
- 单点注销配置文件 (Single Logout Profile, SLO):允许多个会话同时注销。
2.6 元数据 (Metadata)
SAML 元数据 (SAML Metadata) 是一种 XML 文档,用于描述 IdP 和 SP 的配置信息,包括实体 ID、服务终结点 URL、支持的绑定、用于签名验证和加密的证书等。 交换元数据是 IdP 和 SP 建立信任关系、实现互操作性的关键步骤。
三、SAML 2.0 Web 浏览器 SSO 工作流程
SAML Web 浏览器 SSO 流程可以由 SP 发起 (SP-initiated SSO) 或由 IdP 发起 (IdP-initiated SSO)。
3.1 SP 发起的 SSO (SP-initiated SSO)
这是最常见的 SSO 流程之一,当用户尝试访问 SP 上的受保护资源时启动。
sequenceDiagram
participant User as 用户 (浏览器)
participant SP as 服务提供者 (SP)
participant IdP as 身份提供者 (IdP)
User->>SP: 1. 尝试访问受保护资源 (GET /app)
activate SP
SP->>User: 2. 检测到未认证,生成 AuthnRequest,重定向用户到 IdP 登录页 (HTTP 302 Redirect + SAMLRequest)
deactivate SP
activate User
User->>IdP: 3. 发送 SAMLRequest 到 IdP (可能通过 HTTP Redirect 或 HTTP POST)
activate IdP
IdP-->>IdP: 4. 认证用户 (如果未登录,提示登录)
IdP->>IdP: 5. 成功认证后,生成 SAML Response (包含 Assertion), 对其签名
IdP->>User: 6. 重定向用户回 SP 的断言消费者服务 (ACS) URL,携带 SAML Response (通常通过 HTTP POST)
deactivate IdP
activate User
User->>SP: 7. 发送 SAML Response 到 SP 的 ACS URL
deactivate User
activate SP
SP->>SP: 8. 验证 SAML Response (数字签名、时间戳、IdP 身份、InResponseTo), 解密 Assertion (如果加密)
SP->>SP: 9. 从 Assertion 中提取用户身份和属性
SP->>SP: 10. 在 SP 侧为用户建立会话
SP->>User: 11. 将用户重定向到其最初请求的资源
deactivate SP
图:SP 发起的 SSO 流程
流程详解:
- 用户访问 SP 资源:用户(通过浏览器)尝试访问 SP 上的一个受保护资源。
- SP 发起认证请求:SP 检测到用户未认证,生成一个
AuthnRequestSAML 消息。 SP 将用户浏览器重定向到 IdP 的单点登录服务 (SSO Service) URL,并在重定向请求中携带AuthnRequest。 (通常使用 HTTP Redirect 绑定传输AuthnRequest)。 - 用户浏览器访问 IdP:浏览器将
AuthnRequest发送到 IdP。 - IdP 认证用户:如果用户尚未在 IdP 处登录,IdP 会提示用户输入凭据进行认证。
- IdP 生成 SAML Response:认证成功后,IdP 生成一个
SAML Response消息,其中包含一个或多个 SAMLAssertion(断言)。 IdP 对该SAML Response(或其中的Assertion) 进行数字签名。 - IdP 重定向回 SP:IdP 将用户浏览器重定向回 SP 的断言消费者服务 (Assertion Consumer Service, ACS) URL,并在重定向请求中通过 HTTP POST 方式(最常用)或 HTTP Redirect 方式携带
SAML Response。 - 用户浏览器提交 SAML Response:浏览器将
SAML Response提交到 SP 的 ACS URL。 - SP 验证 SAML Response:SP 接收到
SAML Response后,会进行一系列验证:- 验证 IdP 的数字签名,确保消息的完整性和真实性。
- 检查时间戳 (
IssueInstant) 和条件 (Conditions),防止重放攻击和过期断言。 - 确认其
InResponseTo属性是否与最初的AuthnRequest的ID匹配。 - 解密断言(如果已加密)。
- SP 提取用户身份并建立会话:验证通过后,SP 从断言中提取用户身份和属性信息。
- SP 授权并访问资源:SP 基于断言中的信息对用户进行授权,并在 SP 端为用户建立一个本地会话。
- 访问受保护资源:SP 将用户重定向到其最初请求的受保护资源,或直接提供服务。
3.2 IdP 发起的 SSO (IdP-initiated SSO)
当用户首先登录到 IdP 门户(例如公司内部的应用仪表盘),然后从那里点击链接访问 SP 应用程序时启动。
sequenceDiagram
participant User as 用户 (浏览器)
participant IdP as 身份提供者 (IdP)
participant SP as 服务提供者 (SP)
User->>IdP: 1. 直接登录 IdP (例如通过门户网站)
activate IdP
IdP-->>IdP: 2. IdP 认证用户
IdP->>IdP: 3. 用户选择访问某个 SP 应用
IdP->>IdP: 4. IdP 生成 SAML Response (包含 Assertion), 对其签名
IdP->>User: 5. 重定向用户回 SP 的 ACS URL,携带 SAML Response (通常通过 HTTP POST)
deactivate IdP
activate User
User->>SP: 6. 发送 SAML Response 到 SP 的 ACS URL
deactivate User
activate SP
SP->>SP: 7. 验证 SAML Response (数字签名、时间戳、IdP 身份), 解密 Assertion (如果加密)
SP->>SP: 8. 从 Assertion 中提取用户身份和属性
SP->>SP: 9. 在 SP 侧为用户建立会话
SP->>User: 10. 将用户重定向到 SP 应用的主页或指定资源
deactivate SP
图:IdP 发起的 SSO 流程
流程详解:
- 用户登录 IdP:用户直接导航到 IdP 提供的门户网站并进行登录。
- IdP 认证用户:IdP 成功认证用户。
- 用户选择 SP 应用:用户在 IdP 门户中选择一个企业应用(即 SP)。
- IdP 生成 SAML Response:IdP 不经 SP 请求,直接生成包含认证断言的
SAML Response,并进行签名。 - IdP 重定向回 SP:IdP 将用户浏览器重定向到 SP 的 ACS URL,并通过 HTTP POST 方式携带
SAML Response。 - 用户浏览器提交 SAML Response:浏览器将
SAML Response提交到 SP 的 ACS URL。 - SP 验证 SAML Response:SP 接收并验证
SAML Response和签名。 - SP 提取身份并建立会话:SP 从断言中提取用户身份和属性,并在本地为用户建立会话。
- 访问 SP 资源:SP 允许用户访问应用程序。
四、SAML 消息结构示例
SAML 消息是基于 XML 的。以下是简化版的 AuthnRequest 和 Response 示例:
4.1 SAML AuthnRequest (SP -> IdP)
当 SP 需要 IdP 认证用户时,会发送 AuthnRequest。
1 |
|
ID:请求的唯一标识符。Version:SAML 协议版本,通常为2.0。IssueInstant:请求生成时间。Destination:IdP 的 SSO 服务 URL。ProtocolBinding:SP 期望 IdP 回复时使用的绑定。AssertionConsumerServiceURL:SP 接收 SAMLResponse的 URL (ACS URL)。saml:Issuer:发出请求的 SP 的实体 ID。samlp:NameIDPolicy:指定期望的用户标识符格式。samlp:RequestedAuthnContext:SP 所要求的认证级别或方法。ds:Signature:SP 对AuthnRequest的数字签名(可选,但推荐用于增强安全性)。
4.2 SAML Response (IdP -> SP)
IdP 在成功认证后发送 Response,其中包含一个 Assertion。
1 |
|
ID:响应的唯一标识符。InResponseTo:引用原始AuthnRequest的ID,用于关联请求和响应。Destination:SP 的 ACS URL。saml:Issuer:发出响应的 IdP 的实体 ID。samlp:Status:认证结果,Success表示成功。ds:Signature:IdP 对整个Response的数字签名(推荐)。saml:Assertion:核心安全断言。saml:Issuer:发出断言的 IdP 的实体 ID。ds:Signature:IdP 对Assertion的数字签名(强烈推荐)。saml:Subject:标识被认证的用户。saml:NameID:用户的唯一标识符,可以是持久的、暂时的或电子邮件地址等格式。saml:SubjectConfirmation:包含SubjectConfirmationData,指定断言的接收者 (Recipient) 和有效期 (NotOnOrAfter)。
saml:Conditions:定义断言有效性的条件,如有效期 (NotBefore和NotOnOrAfter) 和AudienceRestriction(指定断言的预期接收者,即 SP)。saml:AuthnStatement:记录认证事件的详细信息。saml:AttributeStatement:包含用户的额外属性。
saml:EncryptedAssertion:如果敏感信息需要保护,整个Assertion可以被加密。
五、SAML 的安全考虑
SAML 协议的安全性至关重要,以下是一些关键的安全机制和注意事项:
- 数字签名 (XML Digital Signature):
- 作用:确保 SAML 消息(
AuthnRequest、Response或Assertion)在传输过程中未被篡改 (数据完整性),并验证消息的来源 (认证性和不可否认性)。 - 实现:通常使用 XMLDSig 标准。 IdP 使用其私钥对
SAML Response或Assertion进行签名,SP 使用 IdP 的公钥验证签名。 SP 也可以选择签署AuthnRequest,IdP 会使用 SP 的公钥进行验证。 - 挑战:XML 数字签名的实现复杂,容易出错,例如 XML 规范化问题、引用 URI 问题等,可能导致签名验证失败或安全漏洞。
- 作用:确保 SAML 消息(
- XML 加密 (XML Encryption):
- 作用:保护 SAML 断言中包含的敏感信息(例如用户的 NameID 或属性)的机密性,防止中间人窃听。
- 实现:IdP 使用 SP 的公钥加密敏感数据(通常是会话密钥,再用会话密钥加密实际数据),SP 使用其私钥解密。
- 应用:可以加密整个
Assertion(EncryptedAssertion) 或者特定的NameID(EncryptedID) 或Attribute。
- HTTPS/TLS:所有 SAML 通信都应通过 HTTPS/TLS 进行,以提供传输层加密,保护消息在网络传输中的机密性和完整性。
- 时间戳和有效期 (NotBefore/NotOnOrAfter):
Assertion中包含IssueInstant、NotBefore和NotOnOrAfter属性,定义了断言的生成时间及有效期。SP 必须检查这些时间条件,拒绝过早或过期的断言,以防止重放攻击。 InResponseTo验证:在 SP-initiated SSO 中,SP 接收到的SAML Response应该包含一个InResponseTo属性,其值必须与 SP 自己生成的AuthnRequest的ID匹配,以防止响应劫持攻击。Recipient和AudienceRestriction:断言中的Recipient属性应与实际接收断言的 SP 的 ACS URL 匹配。AudienceRestriction明确指出断言的预期接收者,防止断言被非目标 SP 滥用。- 证书管理:IdP 和 SP 之间需要安全地交换并维护用于签名和加密的 X.509 证书。证书的轮换、撤销和存储是重要的安全实践。
- 防止重放攻击 (Replay Attacks):SP 应该维护一个已处理的
Assertion ID列表,拒绝再次处理具有相同 ID 的断言。
六、SAML Bindings 详解
SAML Bindings 定义了 SAML 协议消息如何映射到底层传输协议。
6.1 HTTP Redirect Binding (GET)
- 特点:SAML 消息(通常是
AuthnRequest)会被压缩并 Base64 编码后,作为查询参数附加到 HTTP GET 请求的 URL 中。 - 优点:简单易用,特别适合作为 SP 发送
AuthnRequest的方式,因为浏览器可以轻松处理 URL 重定向。 - 缺点:URL 长度有限制,不适合传输大的 SAML 消息。敏感信息(即使是 Base64 编码)会暴露在 URL 中,可能被浏览器历史记录、服务器日志捕获,存在泄露风险。消息通常需要单独的签名验证 (例如,使用查询参数签名)。
- 用例:SP 向 IdP 发送
AuthnRequest。
6.2 HTTP POST Binding (POST)
- 特点:SAML 消息(通常是
SAML Response)会被 Base64 编码,并嵌入到 HTML 表单的隐藏字段中,通过 HTTP POST 请求提交。 - 优点:没有 URL 长度限制;消息内容不会暴露在 URL 中,相对更安全;消息可以包含完整的 XMLDSig 签名。
- 缺点:需要浏览器自动提交表单(通常通过 JavaScript),用户体验可能略逊于直接重定向。
- 用例:IdP 向 SP 发送
SAML Response,因为它通常包含敏感认证数据。
6.3 HTTP Artifact Binding
- 特点:不是直接传输 SAML 消息,而是传输一个轻量级的 “Artifact” 引用。SP 接收 Artifact 后,会使用 Artifact Resolution Protocol 通过后端通道(例如 SOAP Over HTTP)直接向 IdP 发送请求,以获取实际的 SAML 消息。
- 优点:增强了隐私和安全性,因为敏感的 SAML 消息不会经过用户浏览器,避免了在浏览器端缓存或泄露的风险。后端通信可以是直接安全的连接。
- 缺点:流程更复杂,需要额外的通信往返。
- 用例:当安全性和隐私是最高优先级,并且可以接受额外通信开销时。
七、SAML Profiles 详解
SAML Profiles 将 SAML 的核心组件(断言、协议、绑定)组合起来,以解决特定的用例。
7.1 Web 浏览器 SSO 配置文件
这是 SAML 最核心和最广泛使用的配置文件,旨在通过 Web 浏览器实现用户在多个服务之间的单点登录体验。 前面“工作流程”部分详细描述了其 SP 发起和 IdP 发起的两种主要模式。该配置文件通常结合 HTTP Redirect 和 HTTP POST 绑定使用。
7.2 单点注销配置文件 (Single Logout Profile, SLO)
SLO 配置文件旨在提供一种机制,允许用户在注销一个参与方(IdP 或任何 SP)时,自动终止所有相关的活动会话。
工作原理简述:
- 用户从某个 IdP 或 SP 发起注销请求。
- 该实体向所有关联的 SPs/IdP 发送
LogoutRequest。 - 接收到
LogoutRequest的 SPs/IdP 会终止本地会话,并响应LogoutResponse。 - 这个注销信号会沿着“信任链”传递,直到所有相关会话都被终止。
SLO 的实现通常比 SSO 更复杂,因为它需要各方协同合作,正确处理可能失败的注销请求,并维护会话状态。
八、SAML 2.0 与 OAuth/OpenID Connect 的对比
SAML 2.0、OAuth 2.0 和 OpenID Connect (OIDC) 都是用于身份和访问管理的开放标准,但它们的设计目的、侧重点和适用场景有所不同。
| 特性/协议 | SAML 2.0 | OAuth 2.0 | OpenID Connect (OIDC) |
|---|---|---|---|
| 主要目的 | 认证 (Authentication) 和 授权 (Authorization)(传递身份信息进行 SSO)。 | 授权 (Authorization)(委托访问资源,而非认证用户)。 | 认证 (Authentication)(基于 OAuth 2.0 的身份层)。 |
| 核心机制 | XML-based Assertions (断言) | Access Tokens (访问令牌) | ID Tokens (身份令牌) + Access Tokens |
| 数据格式 | XML | JSON (通常) | JSON (ID Token 是 JWT) |
| 主要用例 | 企业级 SSO / 联合身份管理 (Enterprise SSO/Federated Identity),B2B、B2E 集成。 | 授予第三方应用访问用户资源的权限 (例如,给 SaaS 应用访问 Google Drive 的权限)。 | Web/Mobile 应用用户登录,获得用户身份信息。 |
| 复杂性 | 协议和 XML 结构相对复杂,实现和配置可能需要专业知识。 | 较简单,API 友好,更适合现代 Web 和移动应用。 | 构建在 OAuth 2.0 之上,相对简洁且易于理解。 |
| 传输层 | 主要依赖 HTTP Redirect/POST 绑定,通常在浏览器中进行多次重定向。 | 主要通过后端 API 调用和浏览器重定向获取令牌。 | 与 OAuth 2.0 类似,更依赖于 HTTPS。 |
| 安全机制 | XML 数字签名、XML 加密、时间戳验证。 | HTTPS/TLS、Token Secret、刷新令牌、客户端认证。 | JWT 签名、HTTPS/TLS,基于 OAuth 2.0 的全部安全特性。 |
选择建议:
- SAML 2.0:
- 如果你要在企业环境中实现 SSO,需要连接到企业目录(如 AD FS、Azure AD、Okta 等)。
- 你的用例主要是 B2B (Business-to-Business) 或 B2E (Business-to-Employee) 联合身份。
- 你需要支持传统企业应用,或者对 XML 签名/加密有特定安全合规要求。
- OAuth 2.0:
- 如果你需要让第三方应用(如手机 App、SaaS 服务)获得用户对受保护资源的访问权限。
- 你的用例是授权而非认证。
- OpenID Connect (OIDC):
- 如果你需要实现现代 Web/Mobile 应用的用户登录和身份认证。
- 你的用例更偏向于消费者级应用 (B2C) 或需要更轻量级、API 友好的身份认证方案。
- 你可以利用 OAuth 2.0 的授权能力,并在此基础上获得用户身份信息。
九、总结
SAML 2.0 作为一项成熟的开放标准,在企业级单点登录和联合身份管理领域发挥着不可替代的作用。它通过定义身份提供者 (IdP) 和服务提供者 (SP) 之间的 XML 消息交换协议,使得用户得以一次认证即可无缝访问多个系统,极大地提升了用户体验和 IT 管理效率。尽管其基于 XML 的复杂性对实现和配置提出了较高要求,但其强大的安全机制(如数字签名和 XML 加密)以及广泛的生态支持,使其成为众多组织实现跨域身份验证和授权的首选方案。理解 SAML 的核心概念、工作流程和安全实践,对于构建和维护现代企业级身份管理系统至关重要。
