在Spring Boot中将HTTP定向到HTTPS背后的代理

时间:2018-12-14 04:54:55

标签: spring-boot spring-security

我有一个用Spring Boot(2.0.5)编写的服务器。它位于提供SSL的代理服务器的后面。代理同时接受HTTP(80)和HTTPS(443),并将两者转发到仅在端口2222上接受HTTP的服务器。代理设置了以下请求标头。

  • x-forwarded-for
  • x-forwarded-proto
  • x-forwarded-port

我在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。

1 个答案:

答案 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地址不会对您的应用程序。