PS:禁止拷贝形式转载,转载请以URL形式
1.参考
参考文章:# 实现 tomcat 热加载证书
2.简介
外部tomcat程序中,连接器会有TrustManagerClassName
属性进行配置,通过自定义的TrustManagerClass
来完成证书的校验实现热加载。
内嵌tomcat中,springboot没有把该属性暴露在其设定的application.yml
中,所以本文通过找到该未暴露属性并设置完成证书的热加载。
3.环境
- jdk11
- springboot:2.2.8.RELEASE
4.代码
4.1 application.yml(https配置)
server:
port: 9999
#配置HTTPS
ssl:
key-store: classpath:keystore127.p12
key-store-password: 123123
key-store-type: PKCS12
key-alias: tomcat
trust-store: classpath:keystore127.p12
trust-store-password: 123123
trust-store-type: JKS
trust-store-provider: SUN
client-auth: need
4.2 MyTrustManager(用来完成热校验的类)
import javax.net.ssl.X509TrustManager;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
/**
* @ClassName
* @Description
* @Author dyf
* @Date 2020/8/18
* @Version 1.0
*/
public class MyTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
if(x509Certificates==null||x509Certificates.length==0||s==null||s.length()==0) throw new IllegalArgumentException();
KeyStore store=getKeyStore();
boolean pass=false;
try {
for(X509Certificate certificate:x509Certificates){
certificate.checkValidity();
String theAlias = store.getCertificateAlias(certificate);
if(theAlias!=null)pass=true;
}
} catch (KeyStoreException e) {
e.printStackTrace();
}
if(!pass)throw new CertificateException();
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
if(x509Certificates==null||x509Certificates.length==0||s==null||s.length()==0) throw new IllegalArgumentException();
for(X509Certificate certificate:x509Certificates){
certificate.checkValidity();
}
}
@Override
public X509Certificate[] getAcceptedIssuers() {
ArrayList<X509Certificate> trusts=new ArrayList<>();
try {
KeyStore store=getKeyStore();
Enumeration<String> alias = store.aliases();
while (alias.hasMoreElements()){
String name = alias.nextElement();
if(store.isCertificateEntry(name)){
X509Certificate trust = (X509Certificate) store.getCertificate(name);
trusts.add(trust);
}
}
} catch (Exception e) {
e.printStackTrace();
}
X509Certificate[] trustsArr = trusts.toArray(new X509Certificate[0]);
return trustsArr;
}
/**
* 获取密钥(当前为实时获取,可以按照自己的需要进行缓存,必要时更新)
* @return
* @throws CertificateException
*/
private KeyStore getKeyStore() throws CertificateException {
InputStream is = new FileInputStream("C:/keystore127.p12");
KeyStore ks = null;
try {
ks = KeyStore.getInstance("PKCS12");
ks.load(is, "123456".toCharArray());
} catch (Exception e) {
e.printStackTrace();
}
return ks;
}
}
4.3 TomcatConfiguration(设置加载MyTrustManager )
import com.alibaba.fastjson.JSON;
import org.apache.catalina.connector.Connector;
import org.apache.coyote.http11.Http11NioProtocol;
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @ClassName
* @Description
* @Author dyf
* @Date 2020/8/18
* @Version 1.0
*/
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers((connector)->{
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
protocol.setTrustManagerClassName("MyTrustManager");
});
return factory;
}
}