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 httpd
或 nginx
)必须为您做一些额外的工作。 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/
ProxyPass
和 ProxyPassReverse
是您可能已经拥有的。但是ProxyPreserveHost
和X-Forwarded-Proto
真的很重要。
查看Spring Boot Docs 的这一部分。如果设置了X-Forwarded-For
或X-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 在应用程序中没有配置 IDP 错误
在使用 Oauth、SAML 和 spring-security 的多租户的情况下从 spring-security.xml 中获取错误