Springboot以Tomcat为容器实现http重定向到https的两种方式

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

Springboot以Tomcat为容器实现http重定向到https的两种方式

1 简介
本文将介绍在Springboot中如何通过代码实现Http到Https的重定向,本文仅讲解Tomcat作为容器的情况,其它容器将在以后一一道来。

建议阅读之前的相关文章:

(1) Springboot整合https原来这么简单

(2)HTTPS之密钥知识与密钥工具Keytool和Keystore-Explorer

2 相关概念
2.1 什么叫重定向
所谓重定向,就是本来你想浏览地址A的,但是到达服务端后,服务端认为地址A的界面不在了或者你没权限访问等原因,不想你访问地址A;就告诉你另一个地址B,然后你再去访问地址B。

对于重定向一般有两个返回码:

301:永久性重定向;
302:暂时性重定向。
通过Chrome查看网络详情,记录了几个网站的重定向情况:

网站 域名 重定向代码 重定向后的网址
南瓜慢说 www.pkslow.com 301 https://www.pkslow.com
Google www.google.com 307 https://www.google.com
Apple www.apple.com 307 https://www.apple.com
支付宝 www.alipay.com 301 https://www.alipay.com
QQ www.qq.com 302 https://www.qq.com
百度 www.baidu.com 307 https://www.baidu.com
注:307也是重定向的一种,是新的状态码。

2.2 为什么要重定向
结合我上面特意列的表格,是不是大概想到了为何要做这种重定向?不难发现上面的重定向都在做一件事,就是把http重定向为https。原因如下:

(1)http是不安全的,应该使用安全的https网址;

(2)但不能要求用户每次输入网站都输入https:// 吧,这也太麻烦了,所以大家都是习惯于只输入域名,甚至连www. 都不愿意输入。因此,用户的输入其实都是访问http的网页,就需要重定向到https以达到安全访问的要求。

2.3 如何做到重定向
首先,服务器必须要同时支持http和https,不然也就没有重定向一说了。因为https是必须提供支持的,那为何还要提供http的服务呢?直接访问https不就行了,不是多此一举吗?原因之前已经讲过了,大家是习惯于只输入简单域名访问的,这时到达的就是http,如果不提供http的支持,用户还以为你的网站已经挂了呢。

两种协议都提供支持,所以是需要打开两个Socket端口的,一般http为80,而https为443。然后就需要把所有访问http的请求,重定向到https即可。不同的服务器有不同的实现,现在介绍Springboot+Tomcat的实现。

3 Springboot Tomcat实现重定向
Springboot以Tomcat作为Servlet容器时,有两种方式可以实现重定向,一种是没有使用Spring Security的,另一种是使用了Spring Security的。代码结构如下:

主类的代码如下:

package com.pkslow.ssl;

import com.pkslow.ssl.config.containerfactory.HttpToHttpsContainerFactoryConfig;
import com.pkslow.ssl.config.security.EnableHttpWithHttpsConfig;
import com.pkslow.ssl.config.security.HttpToHttpsWebSecurityConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;

@SpringBootApplication
@Import({EnableHttpWithHttpsConfig.class, HttpToHttpsWebSecurityConfig.class})
//@Import(HttpToHttpsContainerFactoryConfig.class)
@ComponentScan(basePackages = "com.pkslow.ssl.controller")
public class SpringbootSslApplication {

public static void main(String[] args) {
    SpringApplication.run(SpringbootSslApplication.class, args);
}

}
@ComponentScan(basePackages = "com.pkslow.ssl.controller"):没有把config包扫描进来,是因为想通过@Import来控制使用哪种方式来进行重定向。当然还可以使用其它方式来控制,如@ConditionalOnProperty,这里就不展开讲了。

当没有使用Spring Security时,使用@Import(HttpToHttpsContainerFactoryConfig.class);

当使用Spring Security时,使用@Import({EnableHttpWithHttpsConfig.class, HttpToHttpsWebSecurityConfig.class})。

配置文件application.properties内容如下:

server.port=443
http.port=80

server.ssl.enabled=true
server.ssl.key-store-type=jks
server.ssl.key-store=classpath:localhost.jks
server.ssl.key-store-password=changeit
server.ssl.key-alias=localhost
需要指定两个端口,server.port为https端口;http.port为http端口。注意在没有https的情况下,server.port指的是http端口。

3.1 配置Container Factory实现重定向
配置的类为HttpToHttpsContainerFactoryConfig,代码如下:

package com.pkslow.ssl.config.containerfactory;

import org.apache.catalina.Context;
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HttpToHttpsContainerFactoryConfig {

@Value("${server.port}")
private int httpsPort;

@Value("${http.port}")
private int httpPort;

@Bean
public TomcatServletWebServerFactory 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(createHttpConnector());
    return tomcat;
}

private Connector createHttpConnector() {
    Connector connector =
            new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
    connector.setScheme("http");
    connector.setSecure(false);
    connector.setPort(httpPort);
    connector.setRedirectPort(httpsPort);
    return connector;
}

}
createHttpConnector():这个方法主要是实现了在有https前提下,打开http的功能,并配置重定向的https的端口。

3.2 配置Spring security实现重定向
有两个配置类,一个为打开http服务,一个为实现重定向。

EnableHttpWithHttpsConfig主要作用是在已经有https的前提下,还要打开http服务。

package com.pkslow.ssl.config.security;

import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Configuration
public class EnableHttpWithHttpsConfig {

@Value("${http.port}")
private int httpPort;

@Component
public class CustomContainer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory factory) {
        Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
        connector.setPort(httpPort);
        connector.setScheme("http");
        connector.setSecure(false);
        factory.addAdditionalTomcatConnectors(connector);
    }
}

}
HttpToHttpsWebSecurityConfig主要是针对Spring Security的配置,众所周知,Spring Security是功能十分强大,但又很复杂的。代码中已经写了关键的注释:

package com.pkslow.ssl.config.security;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class HttpToHttpsWebSecurityConfig extends WebSecurityConfigurerAdapter {

@Value("${server.port}")
private int httpsPort;

@Value("${http.port}")
private int httpPort;

@Override
protected void configure(HttpSecurity http) throws Exception {
    //redirect to https - 用spring security实现
    http.portMapper().http(httpPort).mapsTo(httpsPort);
    http.requiresChannel(
            channel -> channel.anyRequest().requiresSecure()
    );

    //访问路径/hello不用登陆获得权限
    http.authorizeRequests()
            .antMatchers("/hello").permitAll()
            .anyRequest().authenticated().and();
}

@Override
public void configure(WebSecurity web) throws Exception {
    //过滤了actuator后,不会重定向,也不用权限校验,这个功能非常有用
    web.ignoring()
            .antMatchers("/actuator")
            .antMatchers("/actuator/**");
}

}
4 总结
最后实现了重定向,结果展示:

本文详细代码可在南瓜慢说公众号回复获取。

参考链接:

Springboot 1.4重定向:https://jonaspfeifer.de/redirect-http-https-spring-boot/

原文地址https://www.cnblogs.com/larrydpk/p/12806699.html

相关文章
|
6月前
|
前端开发 Java 应用服务中间件
从零手写实现 tomcat-08-tomcat 如何与 springboot 集成?
该文是一系列关于从零开始手写实现 Apache Tomcat 的教程概述。作者希望通过亲自动手实践理解 Tomcat 的核心机制。文章讨论了 Spring Boot 如何实现直接通过 `main` 方法启动,Spring 与 Tomcat 容器的集成方式,以及两者生命周期的同步原理。文中还提出了实现 Tomcat 的启发,强调在设计启动流程时确保资源的正确加载和初始化。最后提到了一个名为 mini-cat(嗅虎)的简易 Tomcat 实现项目,开源于 [GitHub](https://github.com/houbb/minicat)。
|
3月前
|
网络协议 Java 应用服务中间件
tomcat配置域名及HTTPS
tomcat配置域名及HTTPS
|
1月前
|
Java 网络架构 Kotlin
kotlin+springboot入门级别教程,教你如何用kotlin和springboot搭建http
本文是一个入门级教程,介绍了如何使用Kotlin和Spring Boot搭建HTTP服务,并强调了Kotlin的空安全性特性。
50 7
kotlin+springboot入门级别教程,教你如何用kotlin和springboot搭建http
|
5月前
|
XML 网络协议 Java
JavaWeb -- HTTP -- WEB服务器TOMCAT
JavaWeb -- HTTP -- WEB服务器TOMCAT
|
2月前
|
监控 网络协议 应用服务中间件
【Tomcat源码分析】从零开始理解 HTTP 请求处理 (第一篇)
本文详细解析了Tomcat架构中复杂的`Connector`组件。作为客户端与服务器间沟通的桥梁,`Connector`负责接收请求、封装为`Request`和`Response`对象,并传递给`Container`处理。文章通过四个关键问题逐步剖析了`Connector`的工作原理,并深入探讨了其构造方法、`init()`与`start()`方法。通过分析`ProtocolHandler`、`Endpoint`等核心组件,揭示了`Connector`初始化及启动的全过程。本文适合希望深入了解Tomcat内部机制的读者。欢迎关注并点赞,持续更新中。如有问题,可搜索【码上遇见你】交流。
【Tomcat源码分析】从零开始理解 HTTP 请求处理 (第一篇)
|
1月前
|
SQL JSON 缓存
你了解 SpringBoot 在一次 http 请求中耗费了多少内存吗?
在工作中常需进行全链路压测并优化JVM参数。通过实验可精确计算特定并发下所需的堆内存,并结合JVM新生代大小估算GC频率,进而优化系统。实验基于SpringBoot应用,利用JMeter模拟并发请求,分析GC日志得出:单次HTTP请求平均消耗约34KB堆内存。复杂环境下,如公司线上环境,单次RPC请求内存消耗可达0.5MB至1MB,揭示了高并发场景下的内存管理挑战。
|
6月前
|
前端开发 Java 应用服务中间件
从零手写实现 tomcat-08-tomcat 如何与 springboot 集成?
本文探讨了Spring Boot如何实现像普通Java程序一样通过main方法启动,关键在于Spring Boot的自动配置、内嵌Servlet容器(如Tomcat)以及`SpringApplication`类。Spring与Tomcat集成有两种方式:独立模式和嵌入式模式,两者通过Servlet规范、Spring MVC协同工作。Spring和Tomcat的生命周期同步涉及启动、运行和关闭阶段,通过事件和监听器实现。文章鼓励读者从实现Tomcat中学习资源管理和生命周期管理。此外,推荐了Netty权威指南系列文章,并提到了一个名为mini-cat的简易Tomcat实现项目。
|
5月前
|
缓存 负载均衡 NoSQL
Redis系列学习文章分享---第十四篇(Redis多级缓存--封装Http请求+向tomcat发送http请求+根据商品id对tomcat集群负载均衡)
Redis系列学习文章分享---第十四篇(Redis多级缓存--封装Http请求+向tomcat发送http请求+根据商品id对tomcat集群负载均衡)
78 1
|
5月前
|
Java 应用服务中间件 API
Tomcat处理一个HTTP请求的执行流程的详细解析
Tomcat处理一个HTTP请求的执行流程的详细解析
158 4
|
5月前
|
Java API Spring
Spring Boot中使用Feign进行HTTP请求
Spring Boot中使用Feign进行HTTP请求
下一篇
无影云桌面