【SpringBoot】如何在 Spring Boot 项目中添加 HTTPS

HTTP 与 HTTPS区别


首先,来简单了解一下 HTTP 与 HTTPS 吧。


超文本传输协议 HTTP 协议被用于在 Web 浏览器和网站服务器之间传递数据。HTTP 协议是以明文方式发送数据,不提供任何方式的数据加密,如果攻击者截取了 Web 浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此 HTTP 协议不适合传输一些敏感信息,比如信用卡号、密码等信息。


为了解决 HTTP 协议的这一缺陷,需要使用另一种传输协议:安全套接字层超文本传输协议,也就是 HTTPS 协议。为了数据传输的安全,HTTPS 在HTTP 的基础上加入了 SSL 协议,SSL 依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信进行加密(具体加密原理这里不赘述)。


两者的区别主要为以下四点:

1、https 协议需要到申请 ssl 证书,现在,免费的ssl证书申请机构不少,个人网站使用完全没问题(文末列出几个提供免费证书的网站);


2、http 是超文本传输协议,信息是明文传输,https 则是具有安全性的 ssl 加密传输协议;


3、http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443;


4、http 的连接很简单,是无状态的;HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议,比 http 协议安全。


目前,很多网站都开始启用 HTTPS 协议进行数据传输,这也是保证数据传输安全的一种方式。那么,当我们搭建自己的网站的时候应该怎么启用 HTTPS 呢?下面将介绍如何在 SpringBoot 项目中添加 HTTPS 支持。


KeyTool 生 成自签发证书文件


1、在控制台输入以下命令开始 生成自签发证书


keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore MyKeyStore.p12 -validity 36500


关键参数说明:

  1. -storetype 指定密钥仓库类型 

  2. -keyalg 生证书的算法名称,RSA是一种非对称加密算法 

  3. -keysize 证书大小 

  4. -keystore 生成的证书文件的存储路径(可指定相对路径或绝对路径) 

  5. -validity 证书的有效期(天 为单位)


2、其他设置


然后一路操作,输入相应的设置, 最后在确认是否正确的时候,检查输入的值是否正确,是就输入y 进行确认。



控制台输入以下命令查看密钥库中的信息


keytool -list -v -keystore MyKeyStore.p12 -storepass chengblog


显示结果,可以看到密钥库中已经存有了一个条目



输入 y 确认设置之后,keytool 工具在设置路径下生成  MyKeyStore.p12 文件,当填写文件名称,会在存储在相对路径下,也就是控制台定位到的目录下。将该文件拷贝到项目根目录下。




项目整合


在 application.properties 配置文件中添加以下配置项:


  
  
# 端口
http.port=8080
server.port=443
# 指定签名文件,对应生成的密钥库文件
server.ssl.key-store=classpath:MyKeyStore.p12
# 指定签名密码,设置的密钥库指令
server.ssl.key-store-password=chengblog
# 指定密钥仓库类型,PKCS12
server.ssl.keyStoreType=PKCS12
# 指定别名,生成密钥库的时候进行了设定
server.ssl.keyAlias=tomcat


    重启项目,然后就可以进行访问了 

    https://localhost:443/login/page


    然而访问网站的人并不知道网站使用了 HTTPS 协议,当访问 http://localhost:8080 时就需要进行自动跳转,我们可以添加配置类来实现自动跳转。


    https 配置类代码 HttpsConfig.java,需要在全局配置类中引用入该类。

    package com.wenlincheng.cblog.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.beans.factory.annotation.Value;
    import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
    import org.springframework.context.annotation.Bean;

    /**
    * @ClassName: HttpsConfig
    * @Description: 配置https
    * @Author: Cheng
    * @Date: 2018/9/17 23:29
    * @Version: 1.0.0
    */

    public class HttpsConfig {

       // 监听的http请求的端口 http.port=端口号  如8080
       @Value("${http.port}")
       Integer httpPort;

       //https端口 如443
       @Value("${server.port}")
       Integer httpsPort;

       @Bean
       public TomcatServletWebServerFactory servletContainer() {
           TomcatServletWebServerFactory tomcat = 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);
               }
           };
           tomcat.addAdditionalTomcatConnectors(httpConnector());
           return tomcat;
       }

       @Bean
       public Connector httpConnector(){
           Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
           //表示用 8080 端口来供http访问
           connector.setScheme("http");
           connector.setPort(httpPort);
           connector.setSecure(false);
           //自动重定向到 https 端口 默认为8443 这里设置为443 因为与SVN Server 端口冲突了
           connector.setRedirectPort(httpsPort);
           return connector;
       }
    }


    解决 Mixed Content 错误

    开启 HTTPS 之后,如果在页面中引入了 HTTP 资源,比如这里引入了百度分享的 share.js 文件,由于是 http请求的资源,会被直接 block 掉,造成引入失败,报 Mixed Content (混合内容) 错误。 



    这里介绍一种最简单的解决方法,在页面的 <head></head> 中加入以下代码,浏览器会自动将 http 的请求升级为 https 请求。针对引入该资源,我项目中采用的是直接将百度分享的资源进行本地化,因为百度分享并不支持 https,就算进行请求升级也无能为力。


    <#--http 请求 安全升级为 https -->
    <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">



    免费申请 SSL 证书网站推荐:


    Let's Encrypt

    网站: https://letsencrypt.org/


    阿里云Symantec DV SSL

    网站:https://common-buy.aliyun.com/?commodityCode=cas


    腾讯云DV SSL 证书

    网站:https://cloud.tencent.com/product/ssl




    扫码关注



    ###### 欢迎关注公众号:【皮卡战记】 ![在这里插入图片描述](https://imgconvert.csdnimg.cn/aHR0cDovL2ltZy53ZW5saW5jaGVuZy5jb20vMjAyMDAzMDYxMjM3MzAuanBn?x-oss-process=image/format,png#pic_center)
    评论 1
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    抵扣说明:

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

    余额充值