Spring Security SAML,使用 SAMLContextProviderLB 设置为 HTTPs 方案时重定向到 HTTP 而不是 HTTPS

Posted

技术标签:

【中文标题】Spring Security SAML,使用 SAMLContextProviderLB 设置为 HTTPs 方案时重定向到 HTTP 而不是 HTTPS【英文标题】:Spring Security SAML, Redirects going to HTTP instead of HTTPS when using SAMLContextProviderLB set to HTTPs scheme 【发布时间】:2016-06-21 18:04:02 【问题描述】:

为 SAMLContextProviderLB bean 附加了我的上下文提供程序

**<property name="scheme" value="https"/>**
        <property name="serverName" value="$sp.hostname"/>
        <property name="serverPort" value="#'$sp.ssl.port'=='' ? 443 : '$sp.ssl.port'"/>
        <property name="includeServerPortInRequestURL" value="#'$sp.ssl.port'=='443' ? false : true "/>
        <property name="contextPath" value="/$sp.context.root"/>

我在反向代理后面,所以我正在卸载 SSL 终止。后端服务器本身正在侦听非 SSL,但 webtier 正在为我们终止 SSL 并转发到非 SSL 端口。我已经使用上述属性设置了 SAMLContextProviderLB,因此即使后端是 https,它也会知道将 saml 令牌的预期接收者映射为 https 受众。然而,我在下面的日志中看到的是,当我访问受保护的资源时,它会在浏览器上返回垃圾。当我在浏览器中将其更改为 https 时,它会按预期工作。看到下面的日志表明从 DefaultSavedRequest url 返回的值是 HTTP,而它应该是 HTTPs。

2016-03-07 18:24:11,907 信息 org.springframework.security.saml.log.SAMLDefaultLogger.log:127 - AuthNResponse;SUCCESS;10.4.203.88;https://myserver:89/fct;https://www.myADFS.com/adfs/services/trust;camachof@email.com;;

2016-03-07 18:24:11,909 调试 org.springframework.security.saml.SAMLProcessingFilter.successfulAuthentication:317 - 身份验证成功。更新 SecurityContextHolder 以包含:org.springframework.security.providers.ExpiringUsernameAuthenticationToken@830e9237:主体:camachof@email.com;凭证:[受保护];已认证:真实;详细信息:空;未授予任何权限

2016-03-07 18:24:11,910 调试 org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler.onAuthenticationSuccess:79 - 重定向到 DefaultSavedRequest 网址:http ://myserver:89/fct/page

2016-03-07 18:24:11,911 调试 org.springframework.security.web.DefaultRedirectStrategy.sendRedirect:36 - 重定向到“http://myserver:89/fct/page”

2016-03-07 18:24:11,911 调试 org.springframework.security.web.context.HttpSessionSecurityContextRepository.saveContext:292 - SecurityContext 存储到 HttpSession: 'org.springframework.security.core.context.SecurityContextImpl@830e9237:身份验证:org.springframework.security.providers.ExpiringUsernameAuthenticationToken@830e9237:主体:camachof@email.com;凭证:[受保护];已认证:真实;详细信息:空;未授予任何权限

2016-03-07 18:24:11,912 调试 org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter:97 - SecurityContextHolder 现在清除,请求处理完成

任何想法如何在此设置下将其强制为 HTTPS?提前致谢。

【问题讨论】:

【参考方案1】:

这个问题很老,但如果我发现了其他人可能会发布一个答案。

您的负载均衡器或反向代理(Apache httpdnginx)必须为您做一些额外的工作。 Spring(或Spring Boot)和嵌入式Tomcat(或Jetty)认为他们正在运行一个http服务器。它正在做什么。如果代理传递了一些头变量,Tomcat就会开始认为它正在运行https

以下是 Apache 需要的示例:

ProxyPreserveHost On
RequestHeader add X-Forwarded-Proto https
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/

ProxyPassProxyPassReverse 是您可能已经拥有的。但是ProxyPreserveHostX-Forwarded-Proto 真的很重要。

查看Spring Boot Docs 的这一部分。如果设置了X-Forwarded-ForX-Forwarded-Proto,则需要将其添加到 application.properties 文件中:

server.use-forward-headers=true

和/或

server.forward-headers-strategy=native

取决于您使用的 spring boot 版本。

您还将在该文档中看到您可以为 Tomcat 特定配置添加这些属性:

server.tomcat.remote-ip-header=x-your-remote-ip-header
server.tomcat.protocol-header=x-your-protocol-header

除了上面的内容之外,完成所有这些操作,它就会开始工作。上面的内容本身不足以强制 Tomcat 开始转发带有https 的请求。

我发现因为我的公司有一个基于硬件的负载平衡器(由 Rackspace 管理),所以很难对其进行配置以进行这些更改。所以我们在防火墙/负载平衡器中进行 SSL 终止,然后将请求转发到端口 80 上的 Apache,然后 Apache 将它们转发到端口 8080 上的 Java。是的,这是一团糟。但它让所有这些废话都起作用了。

【讨论】:

以上是关于Spring Security SAML,使用 SAMLContextProviderLB 设置为 HTTPs 方案时重定向到 HTTP 而不是 HTTPS的主要内容,如果未能解决你的问题,请参考以下文章

OpenAM 的 Spring Security SAML HTTP Post 错误

如何使用 spring-security-saml2 配置服务提供者以使用 EncryptedAssertions?

spring security saml使用哪个密钥?

使用 spring-security-saml 在应用程序中没有配置 IDP 错误

在使用 Oauth、SAML 和 spring-security 的多租户的情况下从 spring-security.xml 中获取错误

Spring Security SAML 扩展和@PreAuthorize