我遇到的问题与此问题非常相似: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();
}
}
为了重定向工作。
但我不知道什么是“DEFAULT_PROTOCOL”常数。我尝试在那里添加所有方法(POST,PUT,DELETE,GET等),但它没有帮助。
答案 0 :(得分:5)
重定向专门用于通知客户端(例如Web浏览器)使用给定的URL执行GET
请求,因此重定向的结果不能是PUT
,POST
,DELETE
或任何其他HTTP方法。
在此上下文中,重定向到HTTPS的主要目的是保护连接免受窥探,即确保没有人能够看到机密信息。这适用于GET
,因为您还没有发送机密信息 1 ,假设它是包含机密信息的响应。
将PUT
或POST
重定向到HTTPS毫无意义,因为已经通过不安全的连接发送了有效负载(机密数据)。
在发送数据之前,需要告诉您的客户端使用HTTPS ,即在构建PUT
/ POST
请求时,需要为其提供HTTPS URL。
修复客户端代码,例如生成HTTP PUT
的JavaScript代码,因此它使用HTTPS。重定向太晚了,完全错了。
PUT
的重定向失败实际上是一件好事,因为它会强制您正确保护您的Web应用程序。如果没有失败,你会错误地认为你的网络应用程序是由重定向保护的,而事实上并非如此。
1)GET
也可能包含机密信息,例如在查询字符串中。如果是,则永远不应该使用HTTP发送,因此在这种情况下保护PUT
/ POST
的规则也适用于GET
。