SpringBoot部署SSL證書(shū)(JKS格式)
1、SpringBoot項(xiàng)目如何部署SSL證書(shū) (JKS格式)
1. 獲取 SSL 證書(shū)和私鑰
首先,你需要獲取有效的 SSL 證書(shū)和私鑰。SSL 證書(shū)是一種用于加密通信的數(shù)字證書(shū),它可以通過(guò)購(gòu)買(mǎi)商業(yè) SSL 證書(shū)或使用免費(fèi)的 Let’s Encrypt 證書(shū)獲得。請(qǐng)確保你擁有證書(shū)文件和與之對(duì)應(yīng)的私鑰文件,這通常是以 .pem 和 .key 結(jié)尾的文件或者是jks格式的,本文以jks格式的SSL證書(shū)為例。
2. 配置 Spring Boot 項(xiàng)目
接下來(lái),我們將配置 Spring Boot 項(xiàng)目以使用 SSL。
2.0 項(xiàng)目環(huán)境
- spring boot 2.2.2
- maven
- 一個(gè)域名(各大域名商有售,阿里、騰訊、華為)
- SSL證書(shū)(阿里云上有免費(fèi)的SSL證書(shū),有效期一年)
2.1 將 SSL 證書(shū)和私鑰文件添加到項(xiàng)目
將之前獲取的 SSL 證書(shū)和私鑰文件拷貝到 Spring Boot 項(xiàng)目中的 src/main/resources 目錄下。這樣,證書(shū)文件會(huì)與項(xiàng)目一起打包并在運(yùn)行時(shí)加載。

2.2 配置 application.properties 或 application.yml
在 Spring Boot 項(xiàng)目的配置文件(application.properties 或 application.yml)中添加以下 SSL 相關(guān)配置:
server:
port: 8856
servlet:
context-path: /
ssl:
enabled: true
# 保存SSL證書(shū)的秘鑰庫(kù)的路徑
key-store: classpath:ssl/xxx.com.jks
key-store-password: xxx
# 證書(shū)類(lèi)型
key-store-type: JKS
# key-store-protocol: TLS
2.3 編寫(xiě)controller進(jìn)行測(cè)試
添加一個(gè)controller,測(cè)試是否生效,測(cè)試結(jié)果如下:

通過(guò)上述訪(fǎng)問(wèn)發(fā)現(xiàn),如果通過(guò)http訪(fǎng)問(wèn)會(huì)提示訪(fǎng)問(wèn)需要組合TLS,但是如果用戶(hù)直接通過(guò)這種方式訪(fǎng)問(wèn)的話(huà),存在著極差的用戶(hù)體驗(yàn)。
2.4 編寫(xiě)配置類(lèi)HTTP轉(zhuǎn)HTPPS
當(dāng)用戶(hù)使用http訪(fǎng)問(wèn)的時(shí)候,將http協(xié)議重定向到https端口
(1)修改配置文件
custom: # 自定義http啟動(dòng)端口
http-port: 8857
server:
port: 8856
servlet:
context-path: /
ssl:
enabled: true
#key-alias: alias-key # 別名(可以不進(jìn)行配置)
# 保存SSL證書(shū)的秘鑰庫(kù)的路徑
key-store: classpath:ssl/xxx.com.jks
key-store-password: xxx
# 證書(shū)類(lèi)型
key-store-type: JKS
# key-store-protocol: TLS
(2)添加配置類(lèi)
package org.pp.ssl.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;
import org.springframework.context.annotation.Configuration;
/**
* https配置,將http請(qǐng)求全部轉(zhuǎn)發(fā)到https
* @author P_P
*/
@Configuration
public class HttpsConfig {
@Value("${custom.http-port: 8857}")
private Integer httpPort;
@Value("${server.port}")
private Integer port;
@Bean
public TomcatServletWebServerFactory servletContainer() {
// 將http請(qǐng)求轉(zhuǎn)換為https請(qǐng)求
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint constraint = new SecurityConstraint();
// 默認(rèn)為NONE
constraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
// 所有的東西都https
collection.addPattern("/*");
constraint.addCollection(collection);
context.addConstraint(constraint);
}
};
tomcat.addAdditionalTomcatConnectors(httpConnector());
return tomcat;
}
/**
* 強(qiáng)制將所有的http請(qǐng)求轉(zhuǎn)發(fā)到https
*
* @return httpConnector
*/
@Bean
public Connector httpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
// connector監(jiān)聽(tīng)的http端口號(hào)
connector.setPort(httpPort);
connector.setSecure(false);
// 監(jiān)聽(tīng)到http的端口號(hào)后轉(zhuǎn)向到的https的端口號(hào)
connector.setRedirectPort(port);
return connector;
}
}
(3)啟動(dòng)項(xiàng)目
添加配置類(lèi)之后,啟動(dòng)項(xiàng)目可以看到控制臺(tái)出現(xiàn)了https端口和http端口

再次訪(fǎng)問(wèn)測(cè)試接口,會(huì)發(fā)現(xiàn)地址欄出現(xiàn)了https

(4)同時(shí)開(kāi)啟http和https
如果不想將http請(qǐng)求都轉(zhuǎn)發(fā)到https進(jìn)行處理,可以同時(shí)開(kāi)啟http和https
/**
* 同時(shí)開(kāi)啟http和https
* @author P_P
*/
import org.apache.catalina.connector.Connector;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HttpsConfig {
@Value("${custom.http-port: 8857}")
private Integer httpPort;
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(httpConnector());
return tomcat;
}
@Bean
public Connector httpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setPort(httpPort);
return connector;
}
}
這樣訪(fǎng)問(wèn)8857(http協(xié)議)的端口就不會(huì)進(jìn)行轉(zhuǎn)發(fā)了

3、spring boot配置ssl證書(shū),異常:Invalid keystore format
3.1環(huán)境介紹
springBoot中配置了一個(gè)bean,bean加載的時(shí)候,會(huì)進(jìn)行jks的加載,jks文件放在src/resources下,然后就報(bào)錯(cuò)了,錯(cuò)誤如下。
2023-08-03 22:22:27.261:[ERROR] [main:6839] [org.springframework.boot.SpringApplication.reportFailure:826] --> Application run failed org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat server at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:215) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.startWebServer(ServletWebServerApplicationContext.java:297) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:163) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) at org.ee.authority.AuthorityApplication.main(AuthorityApplication.java:28) Caused by: java.lang.IllegalArgumentException: Invalid keystore format at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:99) ~[tomcat-embed-core-9.0.29.jar:9.0.29] at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:71) ~[tomcat-embed-core-9.0.29.jar:9.0.29] at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:218) ~[tomcat-embed-core-9.0.29.jar:9.0.29] at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1142) ~[tomcat-embed-core-9.0.29.jar:9.0.29] at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:1228) ~[tomcat-embed-core-9.0.29.jar:9.0.29] at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:586) ~[tomcat-embed-core-9.0.29.jar:9.0.29] at org.apache.catalina.connector.Connector.startInternal(Connector.java:1005) ~[tomcat-embed-core-9.0.29.jar:9.0.29] Caused by: java.lang.IllegalArgumentException: standardService.connector.startFailed at org.apache.catalina.core.StandardService.addConnector(StandardService.java:231) at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.addPreviouslyRemovedConnectors(TomcatWebServer.java:278) at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.start(TomcatWebServer.java:197) ... 10 common frames omitted Caused by: org.apache.catalina.LifecycleException: Protocol handler start failed at org.apache.catalina.connector.Connector.startInternal(Connector.java:1008) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardService.addConnector(StandardService.java:227) ... 12 common frames omitted Caused by: java.lang.IllegalArgumentException: Invalid keystore format at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:99) at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:71) at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:218) at org.apache.tomcat.util.net.AbstractEndpoint.bindWithCleanup(AbstractEndpoint.java:1142) at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:1228) at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:586) at org.apache.catalina.connector.Connector.startInternal(Connector.java:1005) ... 14 common frames omitted Caused by: java.io.IOException: Invalid keystore format at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:666) at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:57) at sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224) at sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:71) at java.security.KeyStore.load(KeyStore.java:1449) at org.apache.tomcat.util.security.KeyStoreUtil.load(KeyStoreUtil.java:69) at org.apache.tomcat.util.net.SSLUtilBase.getStore(SSLUtilBase.java:217) at org.apache.tomcat.util.net.SSLHostConfigCertificate.getCertificateKeystore(SSLHostConfigCertificate.java:206) at org.apache.tomcat.util.net.SSLUtilBase.getKeyManagers(SSLUtilBase.java:283) at org.apache.tomcat.util.net.SSLUtilBase.createSSLContext(SSLUtilBase.java:247) at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:97) ... 20 common frames omitted
3.2現(xiàn)象及原因分析
直接用main函數(shù)解析jks文件,一點(diǎn)毛病都沒(méi)有。但是打包后啟動(dòng)Tomact再解析就不行,直接啟動(dòng)單元測(cè)試(完整加載bean的形式)也不行。
后來(lái)發(fā)現(xiàn),在target文件夾下,jks文件的大小變了。查了資料,大概明白錯(cuò)誤的根本原因了:maven編譯或者打包的時(shí)候,對(duì)文件的內(nèi)容進(jìn)行了修改(maven編譯的時(shí)候使用了占位符,替換的時(shí)候使文件發(fā)生了變化),這就導(dǎo)致了jks文件發(fā)生變化。
3.3解決方案
配置MAVEN過(guò)濾JKS等格式的文件,在pom的build配置中增加如下過(guò)濾配置,將jks過(guò)濾掉。(提一句,以下配置中也過(guò)濾了xlsx,是因?yàn)榇虬驟xcel文件也會(huì)壞掉)
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<useDefaultDelimiters>true</useDefaultDelimiters>
<includeEmptyDirs>true</includeEmptyDirs>
<!-- 證書(shū)文件 -->
<nonFilteredFileExtensions>
<nonFilteredFileExtension>pem</nonFilteredFileExtension>
<nonFilteredFileExtension>pfx</nonFilteredFileExtension>
<nonFilteredFileExtension>p12</nonFilteredFileExtension>
<nonFilteredFileExtension>key</nonFilteredFileExtension>
<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
<nonFilteredFileExtension>jks</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
<!-- java文檔插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</build>到此這篇關(guān)于SpringBoot部署SSL證書(shū)(JKS格式)的文章就介紹到這了,更多相關(guān)SpringBoot部署SSL證書(shū)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SSL證書(shū)部署+SpringBoot實(shí)現(xiàn)HTTPS安全訪(fǎng)問(wèn)的操作方法
- SpringBoot添加SSL證書(shū),開(kāi)啟HTTPS方式(單向認(rèn)證服務(wù)端)
- 解決異常:Invalid?keystore?format,springboot配置ssl證書(shū)格式不合法問(wèn)題
- 在Nginx服務(wù)器上安裝SSL證書(shū)完成HTTPS請(qǐng)求的步驟詳解(springboot項(xiàng)目)
- 使用SpringBoot配置https(SSL證書(shū))
- SpringBoot添加SSL證書(shū)的方法
- Springboot項(xiàng)目配置阿里云SSL證書(shū)的實(shí)現(xiàn)步驟
相關(guān)文章
Java ThreadLocal詳解_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
ThreadLocal,很多地方叫做線(xiàn)程本地變量,也有些地方叫做線(xiàn)程本地存儲(chǔ),本文會(huì)詳細(xì)的介紹一下,有興趣的可以了解一下2017-06-06
詳解Java去除json數(shù)據(jù)中的null空值問(wèn)題
這篇文章主要介紹了詳解Java去除json數(shù)據(jù)中的null空值問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Spring Boot拓展XML格式的請(qǐng)求和響應(yīng)操作過(guò)程
在我們開(kāi)發(fā)過(guò)程中,我們經(jīng)常使用的參數(shù)絕大多少事HTML和JSON格式的請(qǐng)求和響應(yīng)處理,但是我們?cè)趯?shí)際開(kāi)發(fā)過(guò)程中,我們可能經(jīng)歷一些,比如對(duì)于XML格式的請(qǐng)求,本文給大家介紹Spring Boot拓展XML格式的請(qǐng)求和響應(yīng),感興趣的朋友一起看看吧2023-10-10
Java的idea連接mongodb數(shù)據(jù)庫(kù)的詳細(xì)教程
這篇文章主要介紹了Java的idea連接mongodb數(shù)據(jù)庫(kù)的詳細(xì)教程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
Spring中BeanFactoryPostProcessors是如何執(zhí)行的
BeanFactoryPostProcessor是Spring容器提供的一個(gè)擴(kuò)展機(jī)制,它允許開(kāi)發(fā)者在Bean的實(shí)例化和初始化之前對(duì)BeanDefinition進(jìn)行修改和處理,這篇文章主要介紹了你知道Spring中BeanFactoryPostProcessors是如何執(zhí)行的嗎,需要的朋友可以參考下2023-11-11
關(guān)于為何說(shuō)JAVA中要慎重使用繼承詳解
Java繼承是面向?qū)ο蟮淖铒@著的一個(gè)特征,然而下面這篇文章主要給大家介紹了關(guān)于為何說(shuō)JAVA中要慎重使用繼承的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08
在JDK和Eclipse下如何編寫(xiě)和運(yùn)行Java Applet
本文主要介紹了在JDK和Eclipse的環(huán)境下如何編寫(xiě)和運(yùn)行Java Applet,圖文方式,適合初學(xué)者學(xué)習(xí)。2015-09-09
解析spring事務(wù)管理@Transactional為什么要添加rollbackFor=Exception.class
這篇文章主要介紹了spring事務(wù)管理@Transactional為什么要添加rollbackFor=Exception.class,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-11-11
一文詳解MySql外連接查詢(xún)?cè)赟pringBoot中的具體使用
外連接通常分為左外連接,右外連接和全外連接,這篇文章主要為大家詳細(xì)介紹了如何在SpringBoot中使用MySql的外連接查詢(xún),需要的可以參考下2025-02-02

