Artifact Binding
Artifact Binding 是什么
Section titled “Artifact Binding 是什么”和普通 POST / Redirect 直接在前信道传完整 SAML 消息不同,Artifact Binding 会把传输拆成两段:
- 前信道只传
SAMLart - 后信道用 SOAP 请求真实的
AuthnRequest或Response
这意味着浏览器侧拿到的只是一个 artifact 引用,真正的消息内容通过服务端之间的 ArtifactResolve / ArtifactResponse 完成交换。
当前库里的公开 API
Section titled “当前库里的公开 API”sp.createLoginRequest(idp, 'artifact')sp.createArtifactResolveRequest(idp, artifact)sp.createArtifactResolveResponse(idp, config?)sp.parseArtifactResolveRequest(idp, xml)sp.parseArtifactResolveResponse(idp, xml, inResponseTo?)sp.parseLoginResponse(idp, 'artifact', request)
idp.createLoginResponse({ sp, binding: 'artifact', ... })idp.createArtifactResolveRequest(sp, artifact)idp.createArtifactResolveResponse({ sp, ... })idp.parseArtifactResolveRequest(sp, xml)idp.parseArtifactResolveResponse(sp, xml, inResponseTo?)idp.parseLoginRequest(sp, 'artifact', request)
一条典型 Artifact 登录流程
Section titled “一条典型 Artifact 登录流程”SP 发起登录
Section titled “SP 发起登录”const frontChannel = sp.createLoginRequest(idp, 'artifact');浏览器只需要携带前信道里的 artifact 数据,不需要携带完整的 XML AuthnRequest。
IdP 侧解析前信道 artifact 请求
Section titled “IdP 侧解析前信道 artifact 请求”const parsed = await idp.parseLoginRequest(sp, 'artifact', { query: { SAMLart: '<artifact>' }});IdP 生成 Artifact 登录响应
Section titled “IdP 生成 Artifact 登录响应”const response = await idp.createLoginResponse({ sp, binding: 'artifact', user: { NameID: 'user@example.com' }});SP 解析 Artifact 登录响应
Section titled “SP 解析 Artifact 登录响应”const parsed = await sp.parseLoginResponse(idp, 'artifact', { query: { SAMLart: '<artifact>', RelayState: 'state-123' }});SOAP 工具层
Section titled “SOAP 工具层”如果你需要自己管理后信道请求,也可以用导出的 Soap 模块:
Soap.sendArtifactResolve()Soap.sendArtifactResponse()Soap.createArt()Soap.parseArt()Soap.encodeXmlToIso88591()
这层更适合:
- 自己接管 Artifact 存储和一次性消费逻辑
- 自己实现后信道请求转发
- 做联调或协议级排错
当前实现已经做的 Artifact 约束
Section titled “当前实现已经做的 Artifact 约束”- 校验
ArtifactResolve/ArtifactResponse的结构 - 校验
Destination - 校验
InResponseTo - 校验
IssueInstant - 解析 resolved message 后继续走常规登录请求 / 响应逻辑
ArtifactResponse中只允许一个 resolved message
为什么会拒绝多个 resolved message
Section titled “为什么会拒绝多个 resolved message”当前实现刻意把这条收紧做得很严格:
- 如果一个
ArtifactResponse里同时塞多个Response/AuthnRequest/LogoutRequest/LogoutResponse - 库会直接抛出
ERR_MULTIPLE_RESOLVED_MESSAGES
这样做的好处是避免“拿第一个继续解析”这种存在歧义的行为,减少 SOAP 包层的消息选择风险。
使用 Artifact 的最佳实践
Section titled “使用 Artifact 的最佳实践”- artifact 只当引用,不在前信道夹带完整消息
- responder metadata 中明确声明
ArtifactResolutionService - SP metadata 中明确声明 artifact 对应的 ACS / ARS
- 业务层自己保存 artifact 的消费状态和过期时间,做单次使用控制
- 后信道出错时记录 SOAP 原文、状态码和
InResponseTo,排查效率会高很多
什么时候不需要 Artifact
Section titled “什么时候不需要 Artifact”如果你的目标只是常规企业 SSO,对端也没有 Artifact 要求,先跑通 redirect + post 一般更直接。Artifact 更适合对消息暴露面、后信道控制和服务端拉取链路有明确要求的系统。