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

本文涉及的产品
容器镜像服务 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

相关文章
|
15天前
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
42 1
|
4月前
|
网络协议 Java 应用服务中间件
tomcat配置域名及HTTPS
tomcat配置域名及HTTPS
|
29天前
|
前端开发 JavaScript 数据库
https页面加载http资源的解决方法
https页面加载http资源的解决方法
49 4
|
3月前
|
前端开发 JavaScript 数据库
https页面加载http资源的解决方法
https页面加载http资源的解决方法
180 7
|
2月前
|
安全 应用服务中间件 网络安全
修复HTTPS升级后出现 Mixed Content: The page at 'https://xxx' was loaded over HTTPS, but requested an insecure frame 'http://xxx'. This request has been blocked; the content must be served over HTTPS. 的问题
修复HTTPS升级后出现 Mixed Content: The page at 'https://xxx' was loaded over HTTPS, but requested an insecure frame 'http://xxx'. This request has been blocked; the content must be served over HTTPS. 的问题
|
3月前
|
安全 网络安全 数据安全/隐私保护
HTTP与HTTPS协议区别及应用场景
在互联网高速发展的今天,HTTP与HTTPS作为数据传输的基石,作用至关重要。HTTP允许客户端与服务器间传输超文本文档,但其数据传输过程未加密,存在安全隐患;HTTPS则在此基础上加入了SSL/TLS协议,实现了数据加密传输,增强了安全性,广泛应用于电子商务、网上银行、政府网站及社交媒体平台等涉及敏感信息传输的领域,有效保护了用户隐私和数据安全。随着网络安全意识提升,HTTPS正逐渐成为主流。
|
5月前
|
JSON 网络协议 安全
《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(1)-HTTP和HTTPS基础知识
【7月更文挑战第16天】本文介绍了HTTP和HTTPS协议的基本概念与作用,强调了理解HTTP协议对使用抓包工具Fiddler的重要性。HTTP是用于Web浏览器与服务器间信息传输的协议,不加密,易被截取,不适合传输敏感信息。HTTPS是HTTP的安全版,通过SSL/TLS提供加密和服务器身份验证,确保数据安全。HTTP请求包括请求行、请求头、空行和可选的请求主体,响应则有响应行、响应头、空行和响应主体。HTTP协议无状态,而HTTPS解决了安全性问题,但也带来了额外的计算开销。Fiddler作为一个强大的抓包工具,可以帮助开发者和测试人员分析HTTP/HTTPS通信,理解请求和响应的结构。
81 4
《吐血整理》保姆级系列教程-玩转Fiddler抓包教程(1)-HTTP和HTTPS基础知识
|
5月前
|
缓存 网络协议 算法
(二)Java网络编程之爆肝HTTP、HTTPS、TLS协议及对称与非对称加密原理!
作为一名程序员,尤其是Java程序员,那必须得了解并掌握HTTP/HTTPS相关知识。因为在如今计算机网络通信中,HTTP协议的作用功不可没,无论是日常上网追剧、冲���、亦或是接口开发、调用等,必然存在HTTP的“影子”在内。尤其对于WEB开发者而言,HTTP几乎是每天会打交道的东西。
99 10
|
5月前
|
安全 程序员 网络安全
HTTP和HTTPS的区别,你真的了解吗?
大家好,我是你们的技术小伙伴小米!今天我们来聊聊HTTP和HTTPS的区别以及HTTPS链接的建立过程,同时了解两种常见的加密算法——对称加密和非对称加密。通过这篇文章,你将深入理解这些网络基础知识,为网站安全保驾护航!
100 7
|
4月前
|
JavaScript 前端开发 Java
【Azure 环境】各种语言版本或命令,发送HTTP/HTTPS的请求合集
【Azure 环境】各种语言版本或命令,发送HTTP/HTTPS的请求合集