將springboot整合https
https和tls的概念這裏就不說了,這裏說一下keytool
1. 什麼是keytool和keystore
keytool 是個密鑰和證書管理工具。它使用戶能夠管理自己的公鑰/私鑰對及相關證書,用於(通過數字簽名)自我認證(用戶向別的用戶/服務認證自己)或數據完整性以及認證服務。在JDK 1.4以後的版本中都包含了這一工具,它的位置爲%JAVA_HOME%\bin\keytool.exe
,所以如果我們想待會在任何位置的cmd窗口都能使用這個命令, 一個是需要jdk, 第二個是需要配置好全局變量
我們需要用keytool生成一個keystore文件
Keystore 傳統理解爲密鑰庫,或者鑰匙串。一個keystore裏面可以放開發者信息、私鑰、公鑰等信息,可以通過別名來進行區分拿取。開發者將錄入自己信息的祕鑰(而非祕鑰庫Keystore)存入APP中,以認證此APP爲自己開發。
2. 創建一個keystore
- 在命令行窗口輸入keystool命令,可以看到它可以做些什麼
- 在命令行工具中輸入以下命令
-alias
你的證書別名
-keyalg
密鑰算法
-keystore
證書庫文件保存的位置和文件名
-keysize
密鑰長度
-validity
證書有效期天數
keytool -genkey -alias http-demo -validity 360 -keyalg RSA -keystore D:/http-demo.keystore
實際情況下,名字和姓氏應該填寫域名
3. 把生成的這個keystore放到項目根目錄下,注意是項目根目錄,而不是module的目錄,也就是整個項目的根目錄
4. 配置application.properties
server:
port: 8089
#證書名字
ssl:
key-store: demo-http.keystore
#祕鑰庫密碼
key-password: zhangguodong
key-store-type: JKS
key-alias: demo-http
這時候啓動springboot,看日誌就發現:
說明已經啓動https協議了,直接訪問http://localhost:8089
,會報錯:
Bad Request
This combination of host and port requires TLS.
改成https再次訪問,瀏覽器會自動轉爲https協議,但是會提示證書不安全
點擊高級-繼續前往localhost 就可以了
我們可以點擊地址欄的不安全標誌來查看證書信息
3. http重定向https
我們也可以讓本來無法訪問的http,通過重定向來訪問https
- 創建配置類:
package com.zgd.springboot.demo.template.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.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author: zgd
* @Date: 2019/3/21 19:36
* @Description:
*/
@Configuration
public class HttpsConfig {
@Bean
public ServletWebServerFactory 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(createHTTPConnector());
return tomcat;
}
private Connector createHTTPConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setSecure(false);
// http 端口
connector.setPort(8081);
//https端口 配置成application中的servlet.port的端口
connector.setRedirectPort(8089);
return connector;
}
}
- connector.setPort 設置http的端口,不需要和servlet.port配置的端口一樣
- connector.setRedirectPort 設置的重定向的https端口, 需要和servlet.port配置的端口一樣
啓動,會發現日誌打印出了http和https的端口
這個時候再訪問http://localhost:8081
就會重定向到https://localhost:8089