1. 获取SSL证书
- 自签名证书(平时测试的时候)
- 从SSL证书授权中心购买证书(生产)
获取自签名证书
使用 JDK
自带的 keytool
生成
# generate certificate
keytool.exe -genkey -keyalg RSA -keystore tomcat.jks
# ls
PS D:\certificate> ls
目录: D:\certificate
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2023/3/25 10:54 2216 tomcat.jks
# transform jks to pkcs12
keytool -importkeystore -srckeystore tomcat.jks -destkeystore tomcat.pkcs12 -deststoretype pkcs12
# ls
PS D:\certificate> ls
目录: D:\certificate
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2023/3/25 10:54 2557 tomcat.jks
-a---- 2023/3/25 10:57 2557 tomcat.pkcs12
2. 在 Springboot 中配置 https
方式一(yml配置 + bean注册)
- 将证书移动至
resources
资源目录 - 修改配置文件,声明证书信息
- 修改内嵌
Tomcat
的servlet
处理配置
application.yml
server:
port: 9999
ssl:
key-alias: tomcat
key-store-password: 123456
key-store-type: PKCS12
key-store: 'classpath:tomcat.pkcs12'
HttpsConfig.java
@Configuration
public class HttpsConfig {
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory containerFactory = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint security = new SecurityConstraint();
security.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
security.addCollection(collection);
context.addConstraint(security);
}
};
containerFactory.addAdditionalTomcatConnectors(createHttpConnector());
return containerFactory;
}
/**
* redirect http to https
* @return connector
*/ private Connector createHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(9999);
return connector;
}
}
方式二(通过代码声明证书配置)
首先关闭 application.yml
中声明的证书配置
@Configuration
public class HttpsConfig {
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory containerFactory = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint security = new SecurityConstraint();
security.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
security.addCollection(collection);
context.addConstraint(security);
}
};
containerFactory.addAdditionalTomcatConnectors(createHttpConnector());
return containerFactory;
}
/**
* redirect http to https * * @return connector
*/ private Connector createHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(9999);
return connector;
}
@Bean
public WebServerFactoryCustomizer<ConfigurableWebServerFactory> containerCustomizer() {
return factory -> {
Ssl ssl = new Ssl();
String cerPath = Objects.requireNonNull(HttpsConfig.class.getClassLoader().getResource("tomcat.pkcs12")).getPath();
ssl.setKeyStore(cerPath);
ssl.setKeyStorePassword("123456");
ssl.setKeyStoreType("PKCS12");
factory.setSsl(ssl);
factory.setPort(9999);
};
}
}
自测
- postman 测试通过
- 服务侧调用
public static void main(String[] args) {
String baseUrl = "https://localhost:9999/timer";
String Authorization_Prefix = "Bearer ";
HashMap<String, String> loginParam = new HashMap<>();
loginParam.put("username", "wl");
loginParam.put("password", "qQNdzD0J");
String loginBody = HttpRequest.post(baseUrl + "/login/web")
.body(JSONUtil.toJsonStr(loginParam))
.execute().body();
HashMap<String, String> loginRes = JSONUtil.toBean(loginBody, HashMap.class);
HashMap<String, String> login = JSONUtil.toBean(String.valueOf(loginRes.get("data")), HashMap.class);
String token = login.get("accessToken");
System.out.println("token = " + token);
String response = HttpRequest.get(baseUrl + "/routine/monthSummary")
.header(Header.AUTHORIZATION, Authorization_Prefix + token).execute().body();
System.out.println(response);
}
// 打印
// token = 8y1REzklrsyr6/hc0qzw4W+ObSQ/90GNgTorrwkdxKPOu1ZQfIam++WJ2gknLM/Qoq3SQWio3wCvU1nhLS7W/Q==
// {"code":0,"msg":null,"data":null}