SAML 2.0(Security Assertion Markup Language)的核心时序原理是:用户(User Agent)、服务提供者(SP)、身份提供者(IdP)三方通过浏览器重定向/POST传递XML格式的SAML消息,完成"SP请求认证 → IdP认证 → 返回断言 → SP验签建会话"的完整SSO流程。
一、核心角色与概念
- SP (Service Provider):提供业务服务(如OA、CRM),需要IdP认证用户。
- IdP (Identity Provider):集中认证、签发SAML断言(Assertion)。
- SAMLRequest (AuthnRequest):SP生成的认证请求。
- SAMLResponse:IdP返回的认证结果,内含断言。
- Assertion:XML安全声明(身份、属性、授权)。
- ACS (Assertion Consumer Service):SP接收SAMLResponse的接口。
- SSO Service:IdP接收SAMLRequest的接口。
- RelayState:SP传递的上下文(如原访问URL),IdP原样回传。
二、SP发起SSO时序(最常用)
-
用户访问SP受保护资源
- 浏览器请求:
https://sp.example.com/protected - SP检查无会话/未认证
- 浏览器请求:
-
SP生成SAMLRequest并重定向到IdP
-
SP构造
<samlp:AuthnRequest>(XML) -
用HTTP Redirect (DEFLATE压缩+Base64)或HTTP POST传递
-
重定向URL示例:
-
浏览器跳转至IdP
-
-
IdP认证用户
- IdP解析SAMLRequest、验证SP合法性
- 检查IdP会话:
- 已登录:跳过登录
- 未登录:展示登录页(账号密码/扫码/域认证)
- 验证凭据成功
-
IdP生成SAMLResponse(含断言)
- 构造
<samlp:Response>→<saml:Assertion> - 断言包含:
- AuthnStatement:认证时间、方式
- AttributeStatement:用户属性(uid、mail、role)
- Conditions:有效期、受众(Audience)
- IdP用私钥签名(断言/整个响应)
- 可选加密断言内容
- 构造
-
IdP返回SAMLResponse到SP的ACS
- 通常用HTTP POST(自动提交表单)
html<form action="https://sp.example.com/acs" method="post"> <input type="hidden" name="SAMLResponse" value="ZZZ"> <input type="hidden" name="RelayState" value="YYY"> </form>- 浏览器POST到SP ACS
-
SP验证、建会话、授权访问
- 解码SAMLResponse
- 验签:用IdP元数据中的公钥验证签名
- 检查:
- 断言有效期、Audience、One-Time Use
- InResponseTo匹配原Request ID
- 提取用户ID/属性 → 本地授权
- 建立SP会话(Cookie/Ticket)
- 重定向到原保护资源
三、IdP发起SSO时序
- 用户在IdP门户点击SP应用链接
- IdP直接生成SAMLResponse
- POST到SP ACS
- SP验签→建会话→授权
- 无SAMLRequest步骤,适合门户跳转
四、关键安全机制
- 签名验签:IdP私钥签名 → SP公钥验证 → 防篡改、防伪造
- 断言有效期:短时效(几分钟),降低泄露风险
- Audience限制:断言仅对指定SP有效
- One-Time Use:断言只能用一次
- 加密:敏感属性加密,防止浏览器查看
五、绑定(传输方式)
- HTTP Redirect:SAMLRequest放URL(查询串)
- HTTP POST:SAMLResponse放表单域(最常用)
- Artifact:传短引用(Artifact),SP后台拉取完整响应
六、时序总结(一句话)
SP发现未认证 → 重定向带SAMLRequest到IdP → IdP认证 → 签发签名断言 → POST回SP ACS → SP验签建会话 → 访问授权。
一、SAML2.0 SP 发起 SSO 标准时序实战
1. 用户访问受保护资源
- 用户浏览器访问 SP:
/protected - SP 检查无本地会话
- 进入 SSO 流程
2. SP 生成并发送 SAMLRequest
- SP 生成
AuthnRequest - 做 DEFLATE 压缩 + Base64
- 拼接 RelayState(原页面 URL)
- 302 重定向到 IdP SSO 地址
典型 URL
https://idp.example.com/sso?SAMLRequest=xxx&RelayState=yyy
3. IdP 接收并验证 SAMLRequest
- 解码、解压 SAMLRequest
- 校验:
- Issuer(SP 实体 ID)是否合法
- ACS URL 是否在白名单
- AssertionConsumerServiceURL 正确性
- 检查 IdP 会话
- 已登录:直接签发断言
- 未登录:展示登录页
4. 用户认证(IdP 侧)
- 输入账号密码/扫码/域登录
- IdP 验证通过
- 建立 IdP 会话(Cookie)
5. IdP 生成 SAMLResponse(核心)
- 构造
Response→ 包含Assertion - Assertion 必须包含:
- Subject(NameID)
- AuthnStatement(认证时间、方式)
- AttributeStatement(用户属性)
- Conditions(有效期、Audience)
- IdP 使用私钥签名(必须)
- Base64 编码
6. IdP 返回给 SP(通过浏览器自动 POST)
返回一个自动提交表单到 SP ACS:
html
<form action="https://sp.example.com/acs" method="post">
<input type="hidden" name="SAMLResponse" value="...">
<input type="hidden" name="RelayState" value="...">
</form>
7. SP ACS 接收并校验(最容易出问题的环节)
- 接收 SAMLResponse
- Base64 解码
- 使用 IdP 公钥验签
- 校验 Assertion 合法性
- 提取 NameID/Attributes
- 建立 SP 本地会话(Cookie / Token)
- 重定向到 RelayState 原始页面
8. 访问成功
用户正常访问受保护资源
二、极简时序图文字版(可直接画 UML)
UserAgent SP IdP
| | |
|--访问资源---->| |
| |无会话 |
|<--302重定向--| |
| | |
|------------SAMLRequest---------->|
| | |
| | 校验SP信息
| | 检查IdP会话
|<-账号密码登录->| |
| | |
| |<--认证通过--------|
| | |
|<---------SAMLResponse(POST)-----|
| | |
|--提交ACS---->| |
| |验签、校验断言 |
| |建本地会话 |
|<--重定向页面--| |
| | |
三、SP 端必须校验清单(开发必看)
1. 签名校验(必做)
- 必须用 IdP 元数据中的公钥验签
- 必须校验整个 Response 或 Assertion 签名
- 签名失效/篡改直接拒绝
2. Assertion 时间校验
NotBefore≤ 当前时间 ≤NotOnOrAfter- 建议允许 3min 时钟漂移
3. Audience 校验
Audience必须等于 SP EntityID- 防止断言被冒用
4. InResponseTo(可选但推荐)
- Response 中的
InResponseTo - 必须等于 SP 发送的 Request ID
- 防重放、防伪造响应
5. Recipient 校验
Recipient必须等于 ACS 地址- 防止被转发到恶意地址
6. NameID 必须存在
- 用于用户身份映射
- 如:uid、email、工号
7. 防重放
- 存储已使用的
Assertion ID - 短时间内禁止重复使用
四、SAML 核心字段速查表(开发对照)
AuthnRequest 关键字段
ID:请求唯一 IDIssueInstant:签发时间Destination:IdP SSO 地址Issuer:SP EntityIDAssertionConsumerServiceURL:SP ACS 地址ProtocolBinding:urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST
Response 关键字段
IDInResponseToVersion="2.0"IssueInstantDestination= ACS URLIssuer= IdP EntityIDStatusCode= Success
Assertion 关键字段
IDIssueInstantIssuer- Subject → NameID
- Conditions
- NotBefore
- NotOnOrAfter
- AudienceRestriction → Audience
- AuthnStatement
- AuthnInstant
- SessionIndex
- AttributeStatement
- Attribute: email, uid, displayName, role 等
五、最常见错误速查(排障必备)
- 验签失败
- IdP 公钥过期/错配
- 签名对象是 Response 还是 Assertion 不一致
- Audience 不匹配
- SP EntityID 写错
- 时间不合法
- SP/IdP 服务器时间不同步
- ACS 地址不匹配
- Recipient/ACS 配置不一致
- RelayState 丢失
- 跳转后回不到原页面
- NameID 格式不兼容
- 邮箱/用户名/持久 ID 不统一