如何使用Spring Boot自动重定向到https

12
我该如何轻松配置嵌入式Tomcat服务器,以将所有HTTP流量重定向到HTTPS?我在一个EC2实例上运行Spring Boot,该实例位于弹性负载均衡器后面。我已经配置了ELB来处理我的SSL(非常棒),它将X-FORWARDED-PROTO头设置为“https”。如果检测到未设置该头,则要重定向用户以强制使用HTTPS(如果他们还没有使用的话)。 到目前为止,我尝试将以下内容添加到我的application.properties文件中,但没有成功:
server.tomcat.protocol-header=x-forwarded-proto
security.require-ssl=true

你是否有一个安全的应用程序(Spring Security是否在类路径上并且是否拦截了你的请求)?请注意,即使如此,重定向也不是自动的(Spring Security与HSTS一起工作,需要客户端理解和遵循头文件中的指令)。 - Dave Syer
1
你好。你解决了吗?我们遇到了类似的问题。我们有一个ec2负载均衡器,终止ssl并使用http返回到Spring boot应用程序。我们可以从负载均衡器中删除https侦听器,但我们宁愿重定向到https。 - hermansen
可能是Spring Boot重定向HTTP到HTTPS的重复问题。 - user41871
4个回答

10

我的答案有点晚,但我最近遇到了这个问题并想发布一个对我有效的解决方案。

起初,我认为设置tomcat使用X-Forwarded头就足够了,但是Tomcat的RemoteIPValve,通常应该处理此情况,却对我没有用。

我的解决方案是添加EmbeddedServletContainerCustomizer并添加ConnectorCustomizer: (请注意,我在这里使用的是Tomcat 8)

@Component
public class TomcatContainerCustomizer implements EmbeddedServletContainerCustomizer {

    private static final Logger LOGGER = LoggerFactory.getLogger(TomcatContainerCustomizer.class);

    @Override
    public void customize(final ConfigurableEmbeddedServletContainer container) {
        if (container instanceof TomcatEmbeddedServletContainerFactory) {
            final TomcatEmbeddedServletContainerFactory tomcat = (TomcatEmbeddedServletContainerFactory) container;
            tomcat.addConnectorCustomizers(connector -> { 
                connector.setScheme("https");
                connector.setProxyPort(443);
            });
            LOGGER.info("Enabled secure scheme (https).");
        } else {
            LOGGER.warn("Could not change protocol scheme because Tomcat is not used as servlet container.");
        }
    }
}
重要的是,您不仅将方案设置为https,还需要设置ProxyPort,否则Spring Boot的所有内部重定向都会路由到端口80。

2
配置属性security.require-ssl在禁用基本身份验证时不起作用(至少在旧版本的Spring Boot中如此)。因此,您可能需要使用类似于以下代码的代码手动保护所有请求:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Inject private SecurityProperties securityProperties;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        if (securityProperties.isRequireSsl()) http.requiresChannel().anyRequest().requiresSecure();
    }
}

您可以在此处查看我的完整答案:Spring Boot将HTTP重定向到HTTPS


0

在这种情况下,使用AWS负载均衡器并在AWS负载均衡器上处理SSL。因此,不需要密钥库文件。 - Halil

0

Spring Boot 2.0 将 http 重定向到 https:

在 @Configuration 中添加以下内容

   @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);
            }
        };
        tomcat.addAdditionalTomcatConnectors(redirectConnector());
        return tomcat;
    }

    private Connector redirectConnector() {
        Connector connector = new Connector(
                TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
        connector.setScheme("http");
        connector.setPort(8080);
        connector.setSecure(false);
        connector.setRedirectPort(8443);
        return connector;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接