为 Spring Boot 中的 Tomcat 添加 HTTPS 地址

在介绍如何添加 HTTPS 前,看复习一下 tomcat 容器的基本配置。在 Spring Boot 项目中,可以内置各种容器。而在使用 spring-boot-starter-web 依赖之后,会默认使用 tomcat 作为容器。以下是在 application.properties 中一些基本配置:

server.port=8088
server.error.path=/404
server.servlet.session.timeout=30m
server.servlet.context-path=/hi
server.tomcat.uri-encoding=utf-8
server.tomcat.basedir=/tmp

其中比较常用的是第一行的端口号配置,以及第四行的 context-path 访问路径配置。最后一行是 Tomcat 运行时,日志和临时文件保存的位置。

HTTPS 配置

理论上来讲 AWS、Google云平台、阿里云等平台都会免费地或收费地提供 HTTPS 服务来保障伺服器的安全性。如果单独买一个 HTTPS 证书的价格也不会特别便宜。好在 JDK 提供了 Java 数字证书管理工具 keytool,生成的命令如下:

keytool -genkey -alias tomcathttps -keyalg RSA -keysize 2048 -keystore tomcat_https.p12 -validity 365

注意它会让你输入一些信息,最重要的就是密码,需要记下来,之后会使用。在这行命令中,

  • genkey 是创建一个新密钥
  • alias 是这个密钥的别名
  • keyalg 提供了加密方法的选择,这里采用的 RSA。(常用的加密方法有以下几种:对称加密DES3DESAES 等,非对称算法RSADSA 等 以及 散列算法SHA-1MD5 等)
  • keysize 表示密钥的长度
  • keystore 指定了密钥保存的位置,注意 .p12 是后缀。
  • validity 表示了密钥有效天数

完成后,就会在指定位置生成一个 tomcat_https.p12 文件了。要使用的時候,需要將它放置到项目的根目录下,然后在 application.properties 中做以下配置:

server.ssl.key-store=tomcat_https.p12
server.ssl.key-alias=tomcathttps
server.ssl.key-store-password=657834

配置成功之后,就可以通过 https://localhost:8088 加上其余的地址访问网站了。(由于证书是自己生成的,大部分浏览器还未提供其信任,只需要添加信任之后即可访问)

还需要注意的是, Spring Boot 本身不支持同时在配置中启动 HTTP 和 HTTPS,所以如果现在想要访问 http://localhost:8080 的话,将会报 Bad Request。这里常见的解决方法就是将 HTTP 请求重定向至 HTTPS 的地址,配置方法如下:

package pers.dc.config;

import org.apache.catalina.Context;
import org.apache.catalina.connector.Connector;
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.springframework.context.annotation.Configuration;

@Configuration
public class TomcatConfig {

    @Bean
    TomcatServletWebServerFactory tomcatServletWebServerFactory() {
        TomcatServletWebServerFactory serverFactory = new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint constraint = new SecurityConstraint();
                constraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                constraint.addCollection(collection);
                context.addConstraint(constraint);
            }
        };
        serverFactory.addAdditionalTomcatConnectors(getTomcatInitialConnector());
        return serverFactory;
    }

    private Connector getTomcatInitialConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        connector.setPort(8088);
        connector.setSecure(false);
        connector.setRedirectPort(8080);
        return connector;
    }
}

这样,在访问 8088端口的 HTTP 访问时,就会被重定向之前的 8080 的 HTTPS 加密地址了。(注意:两个地址不能一样,不然会报错。)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值