SAML HTTP 重定向绑定中未保留查询字符串

Posted

技术标签:

【中文标题】SAML HTTP 重定向绑定中未保留查询字符串【英文标题】:Query string not preserved in SAML HTTP Redirect binding 【发布时间】:2015-09-16 22:17:16 【问题描述】:

我们使用 Spring SAML 安全扩展在我们的应用程序中实现 SAML。我们现在有以下问题:

我们的一位客户正在为其身份提供者提供一个包含参数的 URL。元数据如下所示(为简洁起见,高度缩写):

<EntityDescriptor>
  <IDPSSODescriptor>
    <SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
        Location="https://idp.example.com/login?parameter=value"/>
  </IDPSSODescriptor>
</EntityDescriptor>

可以看出,有一个名为“parameter”的参数,其值为“value”。生成的重定向 URL 中不存在此参数。我调试了一下,发现SAMLProcessorImpl 从绑定中获取MessageEncoder(对于HTTP 重定向是HTTPRedirectDeflateEncoder)并委托对消息进行编码。编码器依次在其buildRedirectURL 方法中执行以下操作:

// endpointURL is https://idp.example.com/login?parameter=value here
URLBuilder urlBuilder = new URLBuilder(endpointURL);

List<Pair<String, String>> queryParams = urlBuilder.getQueryParams();
queryParams.clear(); // whoops

因此,出于某种原因,参数被有意无条件地剥离。

为什么会出现这种情况,我该如何以最有效的方式解决这个问题?

【问题讨论】:

【参考方案1】:

现在我通过扩展HTTPRedirectDeflateEncoder、复制buildRedirectURL 的代码并删除queryParams.clear() 解决了这个问题。因为 URL 是通过简单连接创建的,所以我明确删除了所有保留的 SAML 参数(如SigAlg 等)以避免潜在的安全问题。之后,只需简单的 Spring 配置更改即可将所有内容连接在一起。

不过,我仍然不知道为什么首先要清除列表。

【讨论】:

嗨音乐。我尝试做同样的事情,但我的扩展 HttpRedirectDeflateEncoder 没有生效,我想知道你是否有一个例子来说明你做了什么?我正在尝试按照 SO ***.com/questions/48551925/… 中的描述与 Spring Boot 自动配置进行连接,谢谢! @Fratt 对不起,很想帮助你,但我早就离开了公司。【参考方案2】:

SAML 身份验证请求只能由受信任的实体发送,并带有不可篡改的参数。在根据 HTTP-Redirect 绑定编码的 SAMLAuthnRequest 之外添加一个参数将意味着潜在的攻击者可以随意更改值,而 IDP 将无法检测到这种更改 - 因为该参数不会被数字签名覆盖.

SAML 除了请求本身称为relayState 之外,还提供了一种用于传递安全内容的机制——您可以使用Spring SAML 的WebSSOProfileOptions 来设置它。

以上是清除参数的原因(至少我相信是这样,这个逻辑来自不是我写的 OpenSAML 库),但当然如果你不介意安全隐患,你找到的方法刚刚好。

【讨论】:

谢谢,您的发言确实让我有一些思考。现在,我真的无法想到这可能会产生安全隐患。如果参数被编码为常规路径,即.../login/parameter/value,这会改变吗?该参数不存在安全性;这与在正确的端口上与正确的主机交谈一样重要(在我们的例子中,它是在 IdP 上选择一个领域)。未能提供它只会导致身份验证失败。 IDP 接收请求/响应的 URL 通常是预先静态定义的,因此您需要为每个参数值创建一个端点。向 IDP 发送更多参数(除了 relayState)的另一种方法是使用 AuthnRequest 中的 Extensions 元素。但本质上,如果您认为有人篡改值没有风险,请继续使用 GET 请求解决方案中的参数,它在 IDP 方面需要最少的定制。 参数和值都是固定的。如问题中所述,它们在已签名的 metadata.xml 中明确设置。所以我想一切都很好,而且 OpenSAML 的行为过于严格。再次感谢! 我现在简要检查了 SAML 规范,没有明确提到在使用 HTTP-Redirect 绑定时应该去除额外的参数 - 所以我同意 OpenSAML 在这种情况下可能过于严格。

以上是关于SAML HTTP 重定向绑定中未保留查询字符串的主要内容,如果未能解决你的问题,请参考以下文章

AADSTS750054:SAMLRequest 或 SAMLResponse 必须作为查询字符串参数出现在 SAML 重定向绑定的 HTTP 请求中

使用 Java 创建“HTTP 重定向绑定”SAML 请求

如何验证 HTTP 重定向绑定的 SAML 签名

如何正确解码 Java 中的 SAML 请求(HTTP 重定向)?

如何进行重定向并保留查询字符串?

Spring saml 将请求重定向到 http