为springboot项目配置https分为两大步
- 首先得拥有ssl证书,这里我们使用keytool工具生成,仅限开发测试环境
- 在springboot项目中配置ssl
Keytool是与JDK一起提供的证书管理实用程序,因此需要安装keytool。要检查它,请尝试从终端提示符下运行命令keytool –help。请注意,如果您使用的是Windows,则可能需要从\ bin文件夹中启动它。
生成self-signed ssl证书
keytool documentation 把keystore定义为“加密密钥、X.509证书链和可信证书”的数据库。
密钥库使用的两种最常见的格式是JKS(专用于Java的专有格式)和PKCS12(行业标准格式)。JKS曾经是默认选择,但现在Oracle建议采用PKCS12格式。我们将看看如何同时使用两者。
在密钥库中生成SSL证书
1.打开终端,创建JKS keystore
keytool -genkeypair -alias tomcat -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 3650 -storepass password
或者创建PKCS12 keystore
keytool -genkeypair -alias tomcat -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650 -storepass password
keytool命令参数说明
- genkeypair: generates a key pair;
- alias: the alias name for the item we are generating;
- keyalg: the cryptographic algorithm to generate the key pair;
- keysize: the size of the key. We have used 2048 bits, but 4096 would be a better choice for production;
- storetype: the type of keystore;
- keystore: the name of the keystore;
- validity: validity number of days;
- storepass: a password for the keystore.
当运行前一个命令时,将要求我们输入一些信息,但是我们可以自由地跳过所有信息(只需按Return键即可跳过一个选项)。当被问及信息是否正确时,我们应该输入是。最后,我们按回车键也将密钥库密码用作密钥密码
What is your first and last name?
[Unknown]:
What is the name of your organizational unit?
[Unknown]:
What is the name of your organization?
[Unknown]:
What is the name of your City or Locality?
[Unknown]:
What is the name of your State or Province?
[Unknown]:
What is the two-letter country code for this unit?
[Unknown]:
Is CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
[no]: yes
Enter key password for <tomcat>
(RETURN if same as keystore password):
验证密钥库内容
JKS 格式
keytool -list -v -keystore keystore.jks
PKCS12格式
keytool -list -v -storetype pkcs12 -keystore keystore.p125
假如我们有了JKS keystore,我们可以选择将其转换为PKCS12
将JKS密钥库转换为PKCS12
keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.p12 -deststoretype pkcs12
使用已经存在的证书
如果我们已经获得了SSL证书,则可以将其导入密钥库,并使用它在Spring Boot应用程序中启用HTTPS。
keytool -import -alias tomcat -file myCertificate.crt -keystore keystore.p12 -storepass password
在springboot中配置https
首先我们需要导入keystore到项目resource文件夹或者是根目录
在springboot1.x中开启Https
application.properties
server.port=8443
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=password
server.ssl.key-alias=tomcat
security.require-ssl=true
在springboot2.x中开启Https
server:
ssl:
key-store: classpath:keystore.p12
key-store-password: password
key-store-type: pkcs12
key-alias: tomcat
key-password: password
port: 8443
在springboot中开启配置SSL
springboot application properties的ssl配置项
- server.port: the port on which the server is listening. We have used 8443 rather than the default 8080 port.
- server.ssl.key-store: the path to the key store that contains the SSL certificate. In our example, we want Spring Boot to look for it in the classpath.
- server.ssl.key-store-password: the password used to access the key store.
- server.ssl.key-store-type: the type of the key store (JKS or PKCS12).
- server.ssl.key-alias: the alias that identifies the key in the key store.
- server.ssl.key-password: the password used to access the key in the key store.
为了自动阻挡非https请求,我们使用Spring Security进行配置。
在springboot1.x 设置security.require-ssl 属性为true
在springboot2.x 需继承WebSecurityConfigurerAdapter ,因为security.require-ssl已经过期了
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.requiresChannel()
.anyRequest()
.requiresSecure();
}
}
更多SSl配置参考https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-configure-ssl
Http请求重定向到Https
Spring允许在application.properties(或application.yml)中仅定义一个网络连接器。由于我们已将其用于HTTPS,因此必须以编程方式为Tomcat Web服务器设置HTTP连接器。Spring Boot 1和Spring Boot 2的实现几乎相同。唯一的区别是在Spring Boot 2中已重命名了一些用于服务器配置的类。
Configuring Tomcat for Spring Boot 1
@Configuration
public class ServerConfig {
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@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(getHttpConnector());
return tomcat;
}
private Connector getHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
}
Configuring Tomcat for Spring Boot 2
@Configuration
public class ServerConfig {
@Bean
public ServletWebServerFactory servletContainer() {
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(getHttpConnector());
return tomcat;
}
private Connector getHttpConnector() {
Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
}
将SSL证书分发给客户端
使用自签名SSL证书时,我们的浏览器将不信任我们的应用程序,并会警告用户它不安全。其他客户端也一样。
因为我们的证书存储在keystore中,我们需要提取它。
keytool -export -keystore keystore.jks -alias tomcat -file myCertificate.crt
密钥库可以采用JKS或PKCS12格式。在执行此命令期间,keytool将要求我们提供在本教程开始时设置的密钥库密码(非常安全的密码)。
为了使JRE信任我们的证书,我们需要将其导入cacerts中:JRE信任存储区负责保存所有可以信任的证书。
keytool -importcert -file myCertificate.crt -alias tomcat -keystore $JDK_HOME/jre/lib/security/cacerts
执行过程中需要输入keystore的密码,如果你没有改过默认的密码是changeit或changeme(不同的操作系统不一样),keytool会询问是否信任该证书,我们输入yes
使用自制的浏览器时,会提示ssl证书不可信,如何使浏览器信任证书参考https://www.jianshu.com/p/35c31b865bb9
参考资料:
[SSL证书生成] (https://github.com/X-rapido/CAS_SSO_Record/blob/master/SSL%E8%AF%81%E4%B9%A6%E7%94%9F%E6%88%90.md)