我有一个用Spring Boot(2.0.5)编写的服务器。它位于提供SSL的代理服务器的后面。代理同时接受HTTP(80)和HTTPS(443),并将两者转发到仅在端口2222上接受HTTP的服务器。代理设置了以下请求标头。
我在WebSecurityConfig
类中测试了以下代码,但没有用。
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.requiresChannel().anyRequest().requiresSecure()
.and().
...
}
我还编写了以下代码,将HTTP重定向到HTTPS。但是它也重定向HTTPS流量。但是我只需要重定向HTTP。
import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpsConfiguration {
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
return tomcat;
}
}
我正在寻找一种方法来检出请求标头,如果它是HTTP,我想将其重定向到HTTPS。
答案 0 :(得分:2)
您提供的Spring Security配置应该可以使用。我猜测问题是您没有正确set up Spring Boot to work with proxies。要启用该支持,您应该指定:
server.use-forward-headers=true
注意:如果您的应用程序在Cloud Foundry或Heroku中运行,则server.use-forward-headers属性默认为true。在所有其他情况下,它默认为false。
我会特别注意details around Tomcat。这就是导致大多数人出现问题的原因。 Tomcat依靠其他设置来确定内部代理IP地址是否与默认正则表达式匹配。如果您的代理的IP与正则表达式不匹配,它会静默忽略转发的标头。
如果您在此方面苦苦挣扎,请尝试指定以下内容:
server.tomcat.internal-proxies=.*
注意:其他应用服务器不关心代理IP地址,并且如果客户端可以欺骗X Forwarded标头,那么它也可以欺骗IP地址,因此将其公开给每个IP地址不会对您的应用程序。