一、服务端发布https>https服务
1、准备SSL证书
(1)自签名证书:如果你只是用于开发或测试环境,可以生成一个自签名证书。
(2)CA 签名证书:对于生产环境,应该使用由受信任的证书颁发机构 (CA) 签名的证书。
这里采用生成自签名证书,可以使用keytool工具生成自签名证书(jdk工具):
keytool -genkeypair -alias myapp -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650
这将创建一个有效期为 10 年的自签名证书,并将其存储在 keystore.p12
文件中。你需要提供一些信息,如组织名称等。注意记住密码和别名。
如下图:https>https://i-blog.csdnimg.cn/direct/8da97de68a1448969875ba3fac552ad0.png" width="1192" />
2、配置springboot启用HTTPS并指定SSL证书的位置和密码
用application.properties
或 application.yml都可以。这样配置可以读取环境变量
把证书放在resource的ssl目录下
server:port: 8443ssl:enabled: ${SSL_ENABLED:true}key-store: ${SSL_KEY_STORE:classpath:ssl/keystore.p12}key-store-password: ${SSL_KEY_STORE_PASSWORD:myapptest}keyStoreType: ${SSL_KEY_STORE_TYPE:PKCS12}keyAlias: ${SSL_KEY_ALIAS:myapp}
启动服务即可通过https>https访问了,默认可以设置成false
3、配置docker容器,启动https>https
把证书放在ssl目录下
version: "3"
services:test-https>https:image: openjdk:8-jdkcontainer_name: test-https>httpsrestart: alwaysports:- 22443:22443command: java -jar /opt/test-https>https.jarvolumes:- /home/services/test/:/opt/- /home/services/test/config/:/config/- /home/services/test/ssl/:/ssl/- /home/services/test/template_server/:/template_server/- /home/services/test/patch/:/patch/- /home/log/test/:/logs/environment:- TZ=Asia/Shanghai- SERVICE_HOST=${HOST_IP}- server.port=22443- NACOS_NAMESPACE=${NACOS_NAMESPACE}- NACOS_ADDR=${NACOS_ADDR}#开启https>https,如果不开启则配置为false- SSL_ENABLED=true#以下配置根据实际证书配置- SSL_KEY_STORE=ssl/keystore.p12- SSL_KEY_STORE_PASSWORD=myapptest- SSL_KEY_STORE_TYPE=PKCS12- SSL_KEY_ALIAS=myapp- JAVA_OPTS=-Xmx512m -XX:G1ConcRefinementThreads=4 -XX:MaxDirectMemorySize=1G
二、通过httpinvoke方法https>https服务
跳过证书校验
public class HttpInvokerRequestExecutorWithSession extends SimpleHttpInvokerRequestExecutor {private int connectTimeout=0;private int readTimeout=0;private SSLContext sslContext;private HostnameVerifier hostnameVerifier;private void initSsl() {try {sslContext = SSLContext.getInstance("TLS");sslContext.init(null, new TrustManager[]{new X509TrustManager() {public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {}public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {}}}, new SecureRandom());} catch (KeyManagementException | NoSuchAlgorithmException e) {logger.error("ssl init error:",e);throw new MsrRuntimeException(e.getMessage());}hostnameVerifier = (hostname, session) -> true;}/**** (non-Javadoc)** @see org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor* #prepareConnection(java.net.HttpURLConnection, int)*/protected void prepareConnection(HttpURLConnection con, int contentLength) throws IOException {super.prepareConnection(con, contentLength);if (con instanceof HttpsURLConnection) {if (sslContext == null) {initSsl();}((HttpsURLConnection) con).setSSLSocketFactory(sslContext.getSocketFactory());((HttpsURLConnection) con).setHostnameVerifier(hostnameVerifier);}con.setConnectTimeout(connectTimeout);con.setReadTimeout(readTimeout);}/**** (non-Javadoc)** @see org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor* #validateResponse(org.springframework.remoting.httpinvoker.HttpInvokerClientConfiguration,* java.net.HttpURLConnection)*/protected void validateResponse(HttpInvokerClientConfiguration config, HttpURLConnection con)throws IOException {super.validateResponse(config, con);}public int getConnectTimeout() {return connectTimeout;}public void setConnectTimeout(int connectTimeout) {this.connectTimeout = connectTimeout;}public int getReadTimeout() {return readTimeout;}public void setReadTimeout(int readTimeout) {this.readTimeout = readTimeout;}}
三、feign接口调用https>https服务
跳过证书校验。feign接口的地址还是正常配置http或https>https都支持
import feign.Client;
import feign.Contract;
import feign.RequestInterceptor;
import feign.codec.ErrorDecoder;
import feign.jaxrs.JAXRSContract;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;@Configuration
public class FeignConfiguration {@Autowiredprivate BusinessConfig businessConfig;/*** yaml中的配置未生效,暂时在配置类中配置*/@Beanpublic Contract getFeignContract() {return new JAXRSContract();}@Beanpublic ErrorDecoder getFeignErrorDecoder() {return new FeignExceptionDecoder();}@Beanpublic OkHttpClient okHttpClient() {if(businessConfig.getRootServiceUrl() != null && businessConfig.getRootServiceUrl().contains("https>https")){try {TrustManager[] trustManagers = getTrustManager();if (trustManagers == null || trustManagers.length == 0) {throw new IllegalStateException("Failed to create trust managers");}SSLSocketFactory sslSocketFactory = getSSLSocketFactory();if (sslSocketFactory == null) {throw new IllegalStateException("Failed to initialize SSL socket factory");}return new OkHttpClient.Builder().readTimeout(60, TimeUnit.SECONDS).connectTimeout(60, TimeUnit.SECONDS).writeTimeout(120, TimeUnit.SECONDS).connectionPool(new ConnectionPool()).sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManagers[0]).hostnameVerifier((hostname, session) -> true).build();} catch (Exception e) {throw new RuntimeException("Failed to create OkHttpClient", e);}}return new OkHttpClient.Builder().readTimeout(60, TimeUnit.SECONDS).connectTimeout(60, TimeUnit.SECONDS).writeTimeout(120, TimeUnit.SECONDS).connectionPool(new ConnectionPool()).build();}@Beanpublic RequestInterceptor requestInterceptor() {return new CustomRequestInterceptor(businessConfig);}@Beanpublic Client feignClient(OkHttpClient okHttpClient) {return new CustomClient(new feign.okhttp.OkHttpClient(okHttpClient));}private TrustManager[] getTrustManager() {try {TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {public X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}public void checkClientTrusted(X509Certificate[] certs, String authType) {}public void checkServerTrusted(X509Certificate[] certs, String authType) {}}};return trustAllCerts;} catch (Exception e) {throw new RuntimeException(e);}}private SSLSocketFactory getSSLSocketFactory() {try {SSLContext sc = SSLContext.getInstance("TLS");sc.init(null, getTrustManager(), new SecureRandom());return sc.getSocketFactory();} catch (Exception e) {throw new RuntimeException(e);}}}