相关文章推荐
八块腹肌的地瓜  ·  Reference for writing ...·  7 月前    · 
腼腆的酱牛肉  ·  sys.dm_exec_query_stat ...·  8 月前    · 
欢快的乌冬面  ·  一份不可多得的 TS ...·  1 年前    · 

Spring Boot。无论我指定哪个HTTPS端口,Tomcat都会重定向到HTTPS 8443

4 人关注

我使用了一种相当标准的方法,将Spring Boot的嵌入式Tomcat从HTTP重定向到HTTPS,这在许多教程中都有重复。该方法对HTTP 8080和HTTPS 8443端口完全有效,这些端口也在这些教程中重复作为例子。然而,将这些端口的数字改为较少使用的值,会产生一些问题,如进一步描述。

教程中的方法如下。应用属性。

server.http.port=8080
server.http.interface=0.0.0.0
server.port: 8443
server.ssl.enabled: true
server.ssl.key-store: classpath:selfsigned.jks
server.ssl.key-store-password: password
server.ssl.key-store-type: JKS
server.ssl.key-alias: selfsigned

然后配置额外的HTTP端口。

@Component
public class HttpServer {
    @Value("${server.port}") int HTTPS_PORT;
    @Bean
public ServletWebServerFactory servletContainer(@Value("${server.http.port}") int httpPort) {
        Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
        connector.setPort(httpPort);
        connector.setRedirectPort(HTTPS_PORT);
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
            @Override
protected void postProcessContext(Context context) {
                ((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
        tomcat.addAdditionalTomcatConnectors(connector);
        return tomcat;

以及最后,安全的配置。

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
protected void configure(HttpSecurity http) throws Exception{
        http.cors().and().csrf().disable();
        http.requiresChannel().anyRequest().requiresSecure();
        http.headers().frameOptions().sameOrigin();
        http.portMapper()
                .http(Integer.parseInt(Prop.get("server.http.port")))
                .mapsTo(Integer.parseInt(Prop.get("server.port")));
    @Bean
CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("*"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;

与教程唯一不同的是,我禁用了TomcatServletWebServerFactory中的Jar清单文件的扫描,因为如果包含tomcat-embed-jasper,就会出现问题(见这里)。

server.http.port=8080
server.port: 8443

正如我所说的,与教程中的工作完全一样。这个。

server.http.port=8080
server.port: 5001

仍然重定向到HTTPS 8443,但在8443没有任何东西,因为Tomcat在8080和5001处监听。

INFO 7360 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 5001 (https) 8080 (http) with context path ''

我扫描了我的应用程序中的每一个文件,包括源代码和二进制文件,都有8443。那里没有一个8443的实例。我还使用调试器来验证setPort()setRedirectPort()portMapper()中的值是否正确。

server.http.port=5000
server.port: 5001
0:0:0:0:0:0:0:1 - - [28/Jan/2021:18:44:46 +0100] "GET /a HTTP/1.1" 302 -
0:0:0:0:0:0:0:1 - - [28/Jan/2021:18:44:46 +0100] "GET /a HTTP/1.1" 302 -
0:0:0:0:0:0:0:1 - - [28/Jan/2021:18:44:46 +0100] "GET /a HTTP/1.1" 302 -
0:0:0:0:0:0:0:1 - - [28/Jan/2021:18:44:46 +0100] "GET /a HTTP/1.1" 302 -

直到浏览器抱怨有太多的重定向。

该网站是在localhost上测试的,证书无效,因此Chrome要求安全例外。不过,Chrome还是把网站放到了HTTP严格传输安全中,可以在chrome://net-internals/#hsts上验证。会不会是Spring Boot在HSTS头文件中发送了什么,导致重定向到8443?

总而言之,似乎80808443有些特殊,并在某处声明,可能在Tomcat或Spring Boot中。如何摆脱这些默认值? 有什么方法可以调试,例如,重定向背后的原因?增加Tomcat、Spring Boot日志的粗略程度?

更新1为了禁用HSTS,我修改了安全代码。

    http.headers().frameOptions().sameOrigin()
            .httpStrictTransportSecurity().disable();

并从Chrome的HSTS中删除了localhost,但这并没有帮助。

更新2当应用程序在具有有效证书的外部服务器上运行时,该问题仍然存在。

项目的依赖性。

 <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.projectreactor</groupId>
<artifactId>reactor-spring</artifactId>
<version>1.0.1.RELEASE</version>
</dependency>