Springboot
适用于 jar 直接运行
单向
- yml
mydefine:
port: 8081
server:
port: 8011
ssl:
enabled: true
key-store: classpath:certificate/server.p12 # src/main/resources/certificate/server.p12
key-store-password: 123456
key-store-type: PKCS12
- SSLConfig
@Configuration
public class SSLConfig {
// http 请求端口
@Value("${mydefine.port}")
private int serverPortHttp;
// HTTPS 请求端口
@Value("${server.port}")
private int serverPortHttps;
@Bean
public Connector connector (){
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
//Connector监听的http的端口号
connector.setPort(serverPortHttp);
connector.setSecure(false);
//监听到http的端口号后转向到的https的端口号
connector.setRedirectPort(serverPortHttps);
return connector;
}
//springboot 2.x 可用
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory(Connector connector){
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;
}
}
双向
- yml
mydefine:
port: 8082
server:
port: 8022
ssl:
enabled: true
key-store-type: PKCS12 # PKCS12 #JKS
key-store: classpath:certificate/server.p12
key-store-password: 123456
key-alias: server
client-auth: none
#trust-store-provider: SUN
trust-store-type: PKCS12
trust-store: classpath:certificate/server.p12
trust-store-password: 123456
- SSLConfig
@Configuration
public class SSLConfig {
// http 请求端口
@Value("${mydefine.port}")
private int serverPortHttp;
// HTTPS 请求端口
@Value("${server.port}")
private int serverPortHttps;
@Bean
public Connector connector (){
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
//Connector监听的http的端口号
connector.setPort(serverPortHttp);
connector.setSecure(false);
//监听到http的端口号后转向到的https的端口号
connector.setRedirectPort(serverPortHttps);
return connector;
}
//springboot 2.x 可用
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory(Connector connector){
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;
}
}
- RestTemplateConfig
@Configuration
public class RestTemplateConfig {
@Value("${server.ssl.key-store-type}")
String clientKeyType;
@Value("${server.ssl.key-store}")
String clientPath;
@Value("${server.ssl.key-store-password}")
String clientPass;
@Value("${server.ssl.trust-store-type}")
String trustKeyType;
@Value("${server.ssl.trust-store}")
String trustPath;
@Value("${server.ssl.trust-store-password}")
String trustPass;
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = null;
try {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
// 客户端证书类型
KeyStore clientStore = KeyStore.getInstance(clientKeyType);
// 加载客户端证书,即自己的私钥
InputStream keyStream = getClass().getClassLoader().getResourceAsStream(clientPath);
clientStore.load(keyStream, clientPass.toCharArray());
// 创建密钥管理工厂实例
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
// 初始化客户端密钥库
keyManagerFactory.init(clientStore, clientPass.toCharArray());
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
// 创建信任库管理工厂实例
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore trustStore = KeyStore.getInstance(trustKeyType);
InputStream trustStream = getClass().getClassLoader().getResourceAsStream(trustPath);
trustStore.load(trustStream, trustPass.toCharArray());
// 初始化信任库
trustManagerFactory.init(trustStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
// 建立TLS连接
SSLContext sslContext = SSLContext.getInstance("TLS");
// 初始化SSLContext
sslContext.init(keyManagers, trustManagers, new SecureRandom());
// INSTANCE 忽略域名检查
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
CloseableHttpClient httpclient = HttpClients
.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
requestFactory.setHttpClient(httpclient);
requestFactory.setConnectTimeout((int) Duration.ofSeconds(15).toMillis());
restTemplate = new RestTemplate(requestFactory);
} catch (KeyManagementException | FileNotFoundException | NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException e) {
e.printStackTrace();
}
return restTemplate;
}
}
Tomcat
tomcat/conf/server.xml
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks" type="RSA" certificateKeystorePassword="123456" />
</SSLHostConfig>
</Connector>
或者
<Connector
port="443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150"
SSLEnabled="true"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol="TLS"
keystoreFile="conf/localhost-rsa.jks"
keystorePass="123456" />
Nginx
nginx 配置后 tomcat / jar 不用配置
编辑配置文件 vim /usr/local/nginx/conf/nginx.conf
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# http
server {
listen 80;
server_name localhost 192.168.1.1;
return 301 https://$server_name$request_uri;
}
# https 单向认证
server {
listen 443 ssl;
server_name localhost 192.168.1.1;
ssl_certificate /root/ssl/server.crt;
ssl_certificate_key /root/ssl/server.key;
location / {
# 反向代理
proxy_pass http://localhost:8080;
}
}
# https 双向认证
server {
listen 443 ssl;
server_name localhost 192.168.1.1;
ssl_certificate /root/ssl/server.crt;
ssl_certificate_key /root/ssl/server.key;
ssl_client_certificate /root/ssl/root.crt; # 根证书 也可以是单个的客户端证书
ssl_verify_client on; # 开启双向认证
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
# 反向代理
proxy_pass http://localhost:8080;
}
}
server {
listen 443 ssl;
server_name localhost 192.168.1.1;
ssl_certificate /root/ssl/server.crt;
ssl_certificate_key /root/ssl/server.key;
ssl_client_certificate /root/ssl/root.crt; # 根证书 也可以是单个的客户端证书
ssl_verify_client optional; # 配置校验客户端策略, ssl_client_verify = SUCCESS
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers off;
location / { # 需要双向验证https的接口
if ($ssl_client_verify != SUCCESS) {
return 401;
}
proxy_pass http://localhost:8080;
proxy_connect_timeout 600;
proxy_read_timeout 600;
}
location /other/downloadUpdateFile { # 获取证书版本和下载证书接口,不需要验证Https
proxy_pass http://localhost:8080;
proxy_connect_timeout 600;
proxy_read_timeout 600;
}
}
}
网友评论