由于 IDP 中的 HttpServletRequest URL 和目标 URL 不匹配,OpenSamlAuthenticationProvider.validateSaml2Response 身份验证异常如下所示:
if (StringUtils.hasText(samlResponse.getDestination()) && !recipient.equals(samlResponse.getDestination())) {
throw this.authException("invalid_destination", "Invalid SAML response destination: " + samlResponse.getDestination());
}...
- HttpServletRequest URL 返回发出 SAML 请求的应用服务器的主机名 (localhost:port) 而不是 dns 名称。
- 我们的应用在负载均衡器后面。
- 我们试图将 proxyName 和 proxyHost 添加到 Tomcat 中的 Http 连接器。我们的协议(protocol)仍然不匹配,我们不相信这是正确的方法。
- 这一定是一个非常普遍的问题,以至于我们没有使用的 Spring SAML 扩展有一个配置类来处理这个确切的问题。
- 我不认为我们可以使用拦截器,因为 HttpServletRequest URL 是不可修改的。
想知道是否有其他人处理过类似的事情并找到了解决方案。
最佳答案
首先,让我们通过启用详细登录来确定不匹配的位置 例如,对于 log4j 配置片段片段将如下所示:
...
log4j.logger.org.springframework.security.saml2.provider.service.authentication=TRACE
log4j.logger.org.opensaml.saml.saml2.assertion.impl=TRACE
其次,让我们像下面这样制作RelyingPartyRegistrationRepository
(调用assertionConsumerServiceLocation
将覆盖元数据中的值)
@Bean
public RelyingPartyRegistrationRepository relyingPartyRegistrationRepository1() {
String consumerServiceLocationFixed = "https://some_host:some_port/some_path/login/saml2/sso/{registrationId}";
RelyingPartyRegistration rp = RelyingPartyRegistrations
.fromMetadataLocation("assertingPartyMetadataLocation")
.assertionConsumerServiceLocation(consumerServiceLocationFixed)
.registrationId("some_idp")
.build();
return new InMemoryRelyingPartyRegistrationRepository(rp);
}
有关更多信息,请随时查看惊人的 https://docs.spring.io/spring-security/site/docs/5.4.1/reference/html5/#servlet-saml2文档(比旧的 https://spring.io/projects/spring-security-saml 的文档好多了)
关于Spring Security SAML2(不是 SAML 扩展)- 由于 HttpServerRequest URL 和目标 URL 不匹配导致的身份验证验证异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59586094/