Spring Boot configure SSL to implement https request
1. Generate SSL certificate
- Professional SSL certificates are more expensive. You can apply for free SSL certificates on Tencent Cloud or Alibaba Cloud.
- If you are just doing a simple demo, you can use the keytool tool that comes with java to generate an SSL certificate.
2. Use keytool to generate SSL certificate
Take the windows system as an example (if it is a linux system, replace keytool.exe with keytool), enter in the terminal
keytool.exe -genkey -alias test -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore test.p12 -validity 3650
Parameter explanation
-genkey: 生成SSL证书
-alias: 证书别名
-storetype: 秘钥仓库类型
-keyalg: 生成证书算法
-keysize: 证书大小
-keystore: 生成证书保存路径
-validity: 证书有效期
Note that after entering the SSL command in the terminal, "What is your first name and last name?" This item needs to be set to your domain name. For local testing, it is localhost, and other options can be ignored.
3. Configure SSL for Spring Boot project
Add the following content in the configuration file application.yml
server:
# 配置端口号,https默认端口号为443,如果443端口被占用,将占用443端口的进程杀死
port: 443
# 配置ssl证书
ssl:
# SSL证书test.p12与application.yml放在同级目录下
key-store: classpath:test.p12
key-store-password: 123456
keyStoreType: PKCS12
keyAlias: test
4. Test whether the SSL configuration is successful
Create HelloController
@RestController
@CrossOrigin(origins = "*")
public class HelloController {
@GetMapping(value = "/hello")
public String sayHello() {
return "Hello World!";
}
}
Use a browser to visit https://localhost/hello to see if the response is correct
(the first time you visit, the browser will warn, this is because the SSL certificate generated by yourself is not recognized by the browser).
If there is an error: check whether the port number in application.yml is 443, and check whether port 443 is occupied by other processes.
5. http request is automatically converted to https request
Modify the entry class HttpsApplication, this configuration method requires SpringBoot2.0 or higher
package com.example.https;
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.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class HttpsApplication {
public static void main(String[] args) {
SpringApplication.run(HttpsApplication.class, args);
}
@Bean
public Connector connector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
// 捕获http请求,并将其重定向到443端口
connector.setScheme("http");
connector.setPort(80);
connector.setSecure(false);
connector.setRedirectPort(443);
return connector;
}
@Bean
public TomcatServletWebServerFactory servletContainer() {
// 对http请求添加安全性约束,将其转换为https请求
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(connector());
return tomcat;
}
}