Spring Boot:从 HTTP 重定向到 HTTPS 会导致 PUT 方法出现 405 错误

2024-01-22

我有一个与此非常相似的问题:重定向 Post 方法 HTTP -> HTTPS - HTTP 状态 405 (Spring boot) https://stackoverflow.com/questions/42108498/redirect-post-method-http-https-http-status-405-spring-boot

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

我尝试了两种配置此类重定向的方法:定义 HTTPS 连接application.properties然后以编程方式添加 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);
}

With 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();
    }

}

为了使重定向工作。

我也看到过这个答案:通过 Catalina 连接器将 POST 请求重定向到 https 端口时,Spring Boot“不支持请求方法‘GET’” https://stackoverflow.com/questions/39528694/spring-boot-request-method-get-not-supported-while-redirecting-post-request

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


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

In this context, the main purpose of redirecting to HTTPS is to secure the connection from snooping, i.e. ensure that no one can see confidential information. This works well for a GET, since you haven't sent confidential information yet1, assuming it is the response that contains confidential information.

重定向PUT or a POST到 HTTPS 是没有意义的,因为你already通过不安全的连接发送有效负载(机密数据)。

需要告诉您的客户端使用 HTTPSbefore它发送数据,即当它构建时PUT / POST请求时,需要为其提供 HTTPS URL。

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

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

1) The GET can contain confidential information too, e.g. in the query string. If it does, it should never have been sent using HTTP, so rules for securing PUT / POST also applies to GET in such cases.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring Boot:从 HTTP 重定向到 HTTPS 会导致 PUT 方法出现 405 错误 的相关文章

随机推荐