【问题标题】:Spring Boot: redirect from HTTP to HTTPS results in 405 error for PUT methodSpring Boot:从 HTTP 重定向到 HTTPS 导致 PUT 方法出现 405 错误
【发布时间】:2018-07-15 17:49:14
【问题描述】:

我有一个和这个非常相似的问题:Redirect Post method HTTP -> HTTPS - HTTP Status 405 (Spring boot)

基本上,我试图通过从 HTTP 到 HTTPS 的重定向使 Spring Boot 同时服务于 HTTP 和 HTTPS。它有效,但仅适用于 GET 请求。如果我执行 PUT 请求,我会收到“不支持请求方法'GET'”错误,所以看起来我的 PUT 请求正在以某种方式转换为 GET 请求。

我尝试了两种配置此类重定向的方法:在 application.properties 中定义 HTTPS 连接,然后以编程方式添加 HTTP,反之亦然。两者都不起作用。

这是第一种方法:

@Bean
public EmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
    TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory() {
        @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);
        }
    };
    addHTTPConnector(factory);
    return factory;
}

private void addHTTPConnector(TomcatEmbeddedServletContainerFactory factory) {
    Connector connector = new Connector(TomcatEmbeddedServletContainerFactory.DEFAULT_PROTOCOL);
    connector.setScheme("http");
    connector.setPort(8080);
    connector.setRedirectPort(8443);
    connector.setSecure(false);
    Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
    protocol.setSSLEnabled(false);
    factory.addAdditionalTomcatConnectors(connector);
}

application.properties:

server.port=8443
server.ssl.key-store=keystore.p12
server.ssl.key-store-password=password
server.ssl.keyStoreType=PKCS12
server.ssl.keyAlias=alias

这是第二种方法:

@Bean
public EmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
    TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory() {
        @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);
        }
    };
    addHTTPSConnector(factory);
    factory.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> connector.setRedirectPort(8443));
    return factory;
}

private void addHTTPSConnector(TomcatEmbeddedServletContainerFactory factory) {
    Connector connector = new Connector(TomcatEmbeddedServletContainerFactory.DEFAULT_PROTOCOL);
    connector.setScheme("https");
    connector.setPort(8443);
    connector.setSecure(true);
    Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
    protocol.setSSLEnabled(true);
    protocol.setKeystoreFile("keystore.p12");
    protocol.setKeystorePass("password");
    protocol.setKeystoreType("pkcs12");
    protocol.setKeystoreProvider("SunJSSE");
    protocol.setKeyAlias("alias");
    factory.addAdditionalTomcatConnectors(connector);
}

我也有

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

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

}

为了使重定向工作。

我也看到了这个答案:Spring Boot "Request method 'GET' not supported" while redirecting POST request to https port through Catalina Connector

但我不知道什么是“DEFAULT_PROTOCOL”常量。我尝试在那里添加所有方法(POST、PUT、DELETE、GET 等),但没有帮助。

【问题讨论】:

    标签: java spring spring-mvc spring-boot tomcat8


    【解决方案1】:

    重定向专门用于通知客户端(例如网络浏览器)使用给定的 URL 执行 GET 请求,因此重定向的结果不能是 PUTPOSTDELETE 或任何其他 HTTP 方法。

    在这种情况下,重定向到 HTTPS 的主要目的是防止连接被窥探,即确保没有人可以看到机密信息。这适用于 GET,因为您尚未发送机密信息1,假设它是包含机密信息的响应。

    PUTPOST 重定向到HTTPS 是没有意义的,因为您已经通过不安全的连接发送了有效负载(机密数据)。

    您的客户端需要在发送数据之前被告知使用 HTTPS,即当它构建 PUT / POST 请求时,需要为其提供一个 HTTPS URL。 p>

    修复客户端代码,例如生成 HTTP PUT 的 JavaScript 代码,因此它使用 HTTPS。重定向为时已晚,而且完全错误。

    PUT 的重定向失败实际上是一件好事,因为它迫使您正确保护您的 Web 应用程序。如果它没有失败,您会错误地认为您的 Web 应用程序受到重定向的保护,而实际上并非如此。

    1) GET 也可以包含机密信息,例如在查询字符串中。如果是这样,它就不应该使用 HTTP 发送,因此保护PUT / POST 的规则在这种情况下也适用于GET

    【讨论】:

    • 天啊,我很尴尬。现在我看到这个问题完全是愚蠢的。无论如何,感谢您快速详细的回答。
    • 这是一个很好的详细答案,解释了基本理论!
    • 我也不好意思。谢谢你的精彩解释。
    猜你喜欢
    • 2017-06-25
    • 2018-03-27
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 2017-10-07
    • 2014-08-31
    • 2020-07-21
    相关资源
    最近更新 更多