【问题标题】:Spring Security SAML: Accept only signed SAML response messages from IDPSpring Security SAML:仅接受来自 IDP 的签名 SAML 响应消息
【发布时间】:2019-01-16 03:38:45
【问题描述】:
我们在我们的 Java 应用程序中使用 Spring Security SAML (v1.0.3) 来实现带有 IDP 的 SAML SSO。
要求:只接受来自 IDP 的签名 SAML 响应消息,如果 SAML 响应没有签名,则抛出异常。
实际结果:即使 SAML 登录响应消息中完全缺少签名信息,它也会被接受并且 Spring Security SAML 库不会抛出异常。
观察:
- 如果 SAML 登录响应消息中存在错误的签名信息,则会引发正确的异常。
- 对于注销消息,我们在扩展元数据生成器中有属性
requireLogoutRequestSigned 和 requireLogoutResponseSigned,用于控制是否应签署注销请求和响应。
- 对于登录响应消息,我们有一个属性
wantAssertionSigned,它指示 SP 是否需要签名断言。
问题:
-
Spring Security SAML 框架中是否有任何属性或方法使 SP 只能接受来自 IDP 的签名登录响应(在消息级别)?
- 据我了解,SAML 响应消息的签名和断言是两件不同的事情。这是正确的吗?
wantAssertionSigned 属性仅启用签名断言,而不启用消息。
【问题讨论】:
标签:
java
spring-security
saml-2.0
spring-saml
spring-security-saml2
【解决方案1】:
- 我找不到这样的配置可能性,不得不添加自定义实现。我将在下面详细说明。
- 是的,这是两个不同的东西。
首先,确保使用了允许签名响应的正确绑定。例如,如果我正确理解 here, lines 578-582 所写的内容,重定向绑定不应在响应本身中有签名
“SAML 协议消息上的任何签名,包括 XML 元素本身,
必须删除。请注意,如果消息的内容包含另一个签名,例如
签名的 SAML 断言,则不会删除此嵌入签名。然而,这样的长度
编码后的消息基本上排除了使用这种机制。因此 SAML 协议
不应使用此机制对包含签名内容的消息进行编码。”
至于 HTTP Post 绑定,它在我最近从事的一个项目中使用,在同一个(如上)文档中,第 839-842 行指出:
“用户代理中介的存在意味着请求者和响应者不能依赖
传输层用于端端身份验证、完整性或机密性保护,并且必须对
而是收到的消息。 SAML 在协议消息上提供签名以进行身份验证和
这种情况下的完整性。表单编码的消息可以在应用 base64 编码之前进行签名。”
基于此,我们决定强制所有由 HTTP Post 绑定处理的响应消息都必须签名。我们将其他绑定保持不变。
为了实现这一点,我对现有 spring 的 HTTPPostBinding 进行了子类化。然后,我指示 spring 提供的 SAMLProcessorImpl 使用此绑定而不是其默认绑定。此自定义绑定实现添加了一个额外的 opensaml 的 SecurityPolicyRule。至于该规则,非常简单的实现会强制所有 SAML 消息进行签名。签名验证留给已经存在的 opensaml 的 SAMLProtocolMessageXMLSignatureSecurityPolicyRule。默认情况下,此选项包含在默认 HTTPPostBinding 中,并且默认情况下也允许缺少签名。如果您决定使用自己的安全策略规则实施,这可能是一个很好的起点。
至于断言签名,我认为默认实现也存在问题,但这可能超出了您的问题范围。
希望这会有所帮助,干杯。