1. 引言
SAML(Security Assertion Markup Language)是一种开放的联合身份标准,用于在不同身份提供方之间交换认证和授权信息。 这些信息可以在多个支持 SAML 的应用和安全域之间共享。因此,SAML 主要用于实现单点登录(SSO)。在本文中,我们将深入讲解 SAML 的核心概念,并以 SAML 2.0 为例进行说明。
2. 什么是 SAML?
SAML 是一种基于 XML 的标记语言,用于在身份提供者(Identity Provider,IdP)和服务提供者(Service Provider,SP)之间共享安全信息。
身份提供者负责对用户进行认证,并将用户的标识及其授权信息发送给服务提供者。
而服务提供者信任身份提供者,并根据其提供的授权级别允许用户访问资源。因此,SAML 提供了一种在不同提供方之间标准化交换安全信息的方式。
SAML 包含安全断言(assertions),这些断言被用于提供方做出访问控制决策。此外,SAML 还定义了协议消息、绑定方式和使用场景(profiles)。我们将在后续章节中详细展开这些内容。
3. 工作流程
如前所述,SAML 最主要的用途是实现单点登录(SSO)。用户只需登录一次,即可访问多个相互信任的服务资源,而无需重复登录。以下是一个典型的 SAML 工作流程:
- 用户向服务提供者请求资源。SP 首先进行安全检查(例如检查是否存在 session cookie):
- ✅ 如果检查通过,直接返回资源(跳转到第8步)
- ❌ 如果未通过,则继续下一步
- SP 将请求重定向到 IdP 的 SSO 服务。通过 URL 参数告知 IdP 这是一个 SAML 请求(SAMLRequest)。参数内容是一个经过解码和解压的
<samlp:AuthnRequest>
元素。 - 用户代理(通常是浏览器)发起 GET 请求访问重定向后的 URL。IdP 处理 AuthnRequest 并识别用户身份。
- IdP 返回一个 XHTML 表单,例如:
其中 SAMLResponse 的值是一个编码后的<form method="post" action="some-action-url" ...> <input type="hidden" name="SAMLResponse" value="some-response-value" /> ... <input type="submit" value="Submit" /> </form>
<samlp:Response>
元素。 - 用户通过该表单向 SP 的断言消费者服务(Assertion Consumer Service)发起请求。
- SP 处理该表单,创建用户的安全上下文,并将用户重定向到最初请求的资源(第1步)。
- 用户再次请求资源,此时已存在有效的安全上下文,因此可以直接访问。
- SP 返回用户请求的资源。
下图展示了整个流程的可视化表示:
总结:服务提供者需要从身份提供者获取安全上下文来判断用户是否有权访问资源。如果存在上下文,资源可直接返回;否则,需通过 SAML 协议向 IdP 请求建立上下文。通过这种方式,用户可以访问所有信任该 IdP 的服务,而无需重复登录。
4. 架构组成
SAML 的架构由多个核心组件构成,主要包括以下四类:
4.1. 断言(Assertions)
断言是 SAML 中最基本的数据单元,用于在 IdP 和 SP 之间传递用户身份和权限信息。它包含在如下 XML 标签中:
<saml:Assertion ...>
..
</saml:Assertion>
SAML 2.0 定义了三种断言类型:
✅ 认证断言(Authentication Statement):告知 SP 用户在某个时间点通过了某种方式的认证。
✅ 属性断言(Attribute Statement):传递与用户相关的属性数据,通常以键值对形式呈现。
✅ 授权断言(Authorization Decision Statement):说明用户是否有权访问某个资源。
一个断言可以包含以上一种或多种断言类型,服务提供者根据这些信息做出访问控制决策。
4.2. 协议(Protocols)
协议定义了 SAML 消息在请求和响应中的封装和使用方式。SAML 2.0 支持多种协议,包括:
- Assertion Query and Request Protocol(断言查询与请求协议)
- Artifact Resolution Protocol(Artifact 解析协议)
- Single Logout Protocol(单点登出协议)
- Authentication Request Protocol(认证请求协议)
- Name Identifier Management Protocol(名称标识符管理协议)
- Name Identifier Mapping Protocol(名称标识符映射协议)
每种协议都对应特定的使用场景,具体细节可参考官方文档。
4.3. 绑定(Bindings)
绑定描述了 SAML 消息如何在网络上传输。例如,SAML 消息可以封装在 SOAP 消息中传输。SAML 2.0 支持的常见绑定包括:
- SAML SOAP Binding(SOAP 绑定)
- Reverse SOAP(PAOS)
- HTTP Redirect Binding(GET 请求绑定)
- HTTP POST Binding(POST 请求绑定)
- HTTP Artifact Binding(Artifact 传输绑定)
- SAML URI Binding(URI 绑定)
绑定方式决定了消息的传输机制,选择时需结合具体场景和安全需求。
4.4. 使用场景(Profiles)
使用场景定义了断言、协议和绑定如何协同工作以支持特定的应用场景。根据官方文档描述:
一个 SAML 的 profile 定义了为支持特定应用使用 SAML 所需的限制和扩展,其目标是通过减少通用标准中不可避免的灵活性来增强互操作性。
SAML 支持多种 profile,其中最常用的是 Web Browser SSO Profile,即浏览器单点登录场景。
5. 总结
本文介绍了 SAML 2.0 标准的核心概念、工作流程及架构组成。SAML 最重要的应用场景是实现单点登录(SSO),通过标准化的身份信息交换,实现了跨域、跨应用的身份认证和授权。对于希望构建统一身份认证体系的企业系统来说,SAML 是一个成熟、广泛采用的技术方案。
✅ Tips:如果你正在集成 SAML 到 Spring Security 或其他 Java 框架中,建议使用 OpenSAML 或 Spring Security SAML 扩展库。踩坑经验表明,手动解析和构造 SAML 消息非常容易出错,建议优先使用成熟库。