ADFS 服务器上的 SAML LogOutRequest 处理失败
Posted
技术标签:
【中文标题】ADFS 服务器上的 SAML LogOutRequest 处理失败【英文标题】:SAML LogOutRequest processing failed on ADFS server 【发布时间】:2013-08-30 06:03:39 【问题描述】:我有 ADFS 服务器作为 IdP。我有单独的 SP 应用程序。这些是在信任圈中定义的。基于 SAML 协议的 SSO 工作正常。当我尝试 SP 发起的注销请求时,ADFS 端出现错误:
MSIS7000:登录请求不符合 Web 浏览器客户端的 WS-Federation 语言或 SAML 2.0 协议 WebSSO 配置文件。
编辑更多来自 ADFS 事件跟踪的详细消息:
MSIS7015:此请求不包含预期的协议消息或根据 HTTP SAML 协议绑定发现不正确的协议参数。
我查看了 mu log out SAML 消息并且看起来正确。只是提到同一个 SP 正在使用 ForgeRocks IdP(前 Sun OpenSSO)正确注销。
Saml loout 请求消息:
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
ID="b00b3f55-f3e3-4935-9e91-da6bf8b62efd"
Version="2.0"
IssueInstant="2013-08-27T09:45:08Z"
Destination="https://00.00.00.00/adfs/ls/"
Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
NotOnOrAfter="2013-08-27T09:50:08Z"
>
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">SPEntityId/</saml:Issuer>
<saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">jsmith@company.com</saml:NameID>
<samlp:SessionIndex>_ea853497-c58a-408a-bc23-c849752d9741</samlp:SessionIndex>
编辑
Lan 建议我必须签署注销请求消息。他是对的。在 OASIS 规范 (http://docs.oasis-open.org/security/saml/v2.0/saml-profiles-2.0-os.pdf) 第 4.4.3.1 节中。它被描述。据此,我正在发送现在签名的消息,但我遇到了同样的问题。
签名消息:
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
ID="aed640c0-9455-49ea-9450-4ad7c08d98e7"
Version="2.0"
IssueInstant="2013-08-29T15:22:45Z"
Destination="https://server/adfs/ls/"
Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
NotOnOrAfter="2013-08-29T03:27:45Z"
>
<saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">user</saml:NameID>
<samlp:SessionIndex>_677952a2-7fb3-4e7a-b439-326366e677db</samlp:SessionIndex>
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">SPIssuer</saml:Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#aed640c0-9455-49ea-9450-4ad7c08d98e7">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>53jjPvQ2Ty1Z+VikwrUwW4Erj3k=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>signed value</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>certificate</X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
我做错了什么?应该在 ADFS 上指定其他端点吗?正如我所得到的,应该与登录请求相同(在我这边工作得很好)。
谢谢, 拉斯特科
【问题讨论】:
【参考方案1】:Finlay 我可以做 SLO :)
之前我曾使用过 ForgeRock 的 IDP,它运行良好,但使用 ADFS 却没有。很明显,微软对与 SAML 消息格式相关的规则进行了限制。我发现的结论:
必须对 LogoutRequest 消息进行签名(SAML 2.0 Profiles doc,Sect 4.4.3.1)。谢谢伊恩。
XML 元素和属性的顺序很重要。此消息的底部是我的注销请求的最终版本。
NameId 必须与从 AuthenticationResponse 接收到的格式相同。它应该包含 ADFS 预期的元素。这些链接帮助了我:Name Identifier (Name ID) claim in the SAML subject 和 SAML LogoutRequest
我必须使用 XmlDsigExcC14NTransform 转换 LogoutRequest 签名,该签名应在 XmlDsigEnvelopedSignatureTransform 之后添加
签名的规范化方法应为http://www.w3.org/2001/10/xml-exc-c14n#
Issuer、NameID 和 SessionIndex 是必需的 XML 元素
命名空间是强制性的:xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" 和 xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
正在运行的最终 LogoutRequest 消息:
<samlp:LogoutRequest ID="f8a62847-92f2-4f0c-936a-df9efe0cc42f"
Version="2.0"
IssueInstant="2013-08-29T20:53:50Z"
Destination="https://server/adfs/ls/"
Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
>
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://sp.com/</saml:Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#f8a62847-92f2-4f0c-936a-df9efe0cc42f">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>W7F1E2U1OAHRXn/ItbnsYZyXw/8=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue></SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate></X509Certificate>
</X509Data>
</KeyInfo>
</Signature>
<saml:NameID xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
Format="http://schemas.xmlsoap.org/claims/UPN"
>user</saml:NameID>
<samlp:SessionIndex>_2537f94b-a150-415e-9a45-3c6fa2b6dd60</samlp:SessionIndex>
【讨论】:
AuthRequest 在 ADFS2.0 上为我工作,无需签名。但是 LogoutRequest 不起作用。为什么会出现这种异常?是否必须签署 LogoutRequest- 当然??【参考方案2】:IIRC SAML 2.0 SP 发起的 SLO 需要在 LogoutRequest 上使用数字签名?这样可以确保没有人欺骗 LogoutRequest 并将用户从所有现有会话中注销。
假设您使用的是 POST 绑定而不是重定向,因为我在 XML 中看不到签名。使用重定向,签名信息作为查询参数传递。
【讨论】:
是的,我知道签名和加密是 SAML 消息的组成部分。我在测试环境中使用它并简化我没有使用这些安全元素的场景。我在这里使用 POST 绑定。我在 ADFS 配置中删除了我的 RelayParty 上的签名。如果必须签名,我假设身份验证请求也会导致失败,但它可以正常工作。 反映负责创建 SamlMessage 的 Microsoft.IdentityServer.Protocols.Saml.dll 和 HttpSamlMessageFactory 发现签名不是强制性的。查看以下代码部分: string value = collection.Get("Signature"); string text2 = collection.Get("SigAlg"); if (!string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(text2)) throw new .. // 一些代码 return base.CreateFromNameValueCollection(baseUrl, collection); 对 AuthnRequest 进行签名不是强制性的...无论绑定如何,它都是可选的。但是,根据规范(SAML 2.0 Profiles doc,Sect 4.4.3.1),当使用异步绑定(POST 或重定向)时,必须对 LogoutRequest 进行签名。我无论如何都不是 ADFS 专家,但如果你故意使 ADFS 不合规,我会感到惊讶......以上是关于ADFS 服务器上的 SAML LogOutRequest 处理失败的主要内容,如果未能解决你的问题,请参考以下文章
ADFS、WIF、WS 联合、SAML 和 STS 之间有啥区别?
Spring SAML ADFS:java.security.InvalidKeyException
由于状态消息为空,ADFS 响应失败时的 Spring SAML 单点登录