java - 在反向代理后面需要 HTTPS 和 Spring Security

标签 java https spring-security reverse-proxy

我有一个使用 Spring Security 保护的 Spring MVC 应用程序。大多数应用程序使用简单的 HTTP 来节省资源,但一小部分处理更多 secret 信息并需要 HTTPS channel 。

security-config.xml 中提取:

<sec:http authentication-manager-ref="authenticationManager" ... >
    ...
    <sec:intercept-url pattern="/sec/**" requires-channel="https"/>
    <sec:intercept-url pattern="/**" requires-channel="http"/>
</sec:http>

在我们决定将其迁移到主服务器之前一切正常,应用服务器在反向代理后面运行。现在 HTTPS 由反向代理处理,应用程序服务器只能看到 HTTP 请求,并且不允许访问 /sec/** 层次结构。

经过一些研究,我发现代理添加了一个 X-Forwarded-Proto: https header (*),但是在 Spring Security HttpServletRequest.isSecure() 用于确定提供的 channel 安全(摘自 SecureChannelProcessor javadoc)。

我如何告诉 Spring Security X-Forwarded-Proto: https header 足以满足安全请求?

我知道我可以报告有关代理配置的部分,但代理管理员真的不喜欢该解决方案,因为代理背后有许多应用程序,配置可能会增长到无法管理的状态。

我目前正在使用带有 XML 配置的 Spring Security 3.2,但我已准备好接受基于 Java 配置和/或更新版本的答案。

(*) 当然,代理会删除传入请求中出现的 header ,因此应用程序可以对此充满信心。

最佳答案

类似于 NeilMcGuigan 的回答,表明解决方案是 servlet 容器端。

Tomcat 甚至更好。有一个 专门用于屏蔽 反向代理的副作用。从 Tomcat 文档中提取 Remote IP Valve :

此阀门的另一个功能是通过请求 header (例如“X-Forwarded -Proto").

阀门配置示例:

<Valve className="org.apache.catalina.valves.RemoteIpValve"
    internalProxies="192\.168\.0\.10|192\.168\.0\.11"
    remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by"
    protocolHeader="x-forwarded-proto" />

这样应用程序本身没有其他配置,如果请求包含 的 header 字段,则对 Request.isSecure() 的调用将返回 true X-Forwarded-Proto=https.

我想到了另外两种可能性,但最终还是更喜欢那个:

  • 使用在 Spring Security ChannelProcessingFilter 之前激活的过滤器,用 HttpServletRequestWrapper 覆盖 isSecure() 来包装请求以处理 X -Forwarded-Proto header - 需要编写和测试过滤器和包装器
  • 使用 Spring BeanPostProcessor 寻找 ChannelProcessingFilter 并手动注入(inject)能够考虑 X-Forwarded-Proto 的 ChannelDecisionManager header - 级别真的太低了

关于java - 在反向代理后面需要 HTTPS 和 Spring Security,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30076551/

相关文章:

spring - 获取运行时错误 java.lang.NoSuchMethodError : org. springframework.core.convert.support.PropertyTypeDescriptor

Node.js 和 Google Pagespeed API

ssl - 在本地主机 IIS 上启用 SSL

google-chrome - 如何从 Chrome 中删除 "is dangerous, so Chrome has blocked it" block ?

spring - 在 Kotlin 上添加 Spring Security 后测试 Spring Controller POST 方法

java - 如何在 JSP 页面中检索并显示数据库中的图像?

java - soap 请求 java 中缺少 header

java - 如何修复 - 按 Intent 进行的唯一扩展关联不起作用

java - 无法刷新 RecyclerView

grails和springsecurity配置问题