diff --git a/common/src/main/java/ink/wgink/common/rpc/rest/request/HttpsClientRequestFactory.java b/common/src/main/java/ink/wgink/common/rpc/rest/request/HttpsClientRequestFactory.java new file mode 100644 index 00000000..7dad0a61 --- /dev/null +++ b/common/src/main/java/ink/wgink/common/rpc/rest/request/HttpsClientRequestFactory.java @@ -0,0 +1,126 @@ +package ink.wgink.common.rpc.rest.request; + +import org.springframework.http.client.SimpleClientHttpRequestFactory; + +import javax.net.ssl.*; +import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.Socket; +import java.security.cert.X509Certificate; + +/** + * @ClassName: HttpsClientRequestFactory + * @Description: + * @Author: wanggeng + * @Date: 2022/3/28 17:34 + * @Version: 1.0 + */ +public class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory { + + @Override + protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException { + try { + if (!(connection instanceof HttpsURLConnection)) { + throw new RuntimeException("An instance of HttpsURLConnection is expected"); + } + + HttpsURLConnection httpsConnection = (HttpsURLConnection) connection; + + TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + + @Override + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } + + } + }; + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + httpsConnection.setSSLSocketFactory(new CustomSSLSocketFactory(sslContext.getSocketFactory())); + httpsConnection.setHostnameVerifier((s, sslSession) -> true); + super.prepareConnection(httpsConnection, httpMethod); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 自定义ssl socker + */ + private static class CustomSSLSocketFactory extends SSLSocketFactory { + private final SSLSocketFactory delegate; + + public CustomSSLSocketFactory(SSLSocketFactory delegate) { + this.delegate = delegate; + } + + // 返回默认启用的密码套件。除非一个列表启用,对SSL连接的握手会使用这些密码套件。 + // 这些默认的服务的最低质量要求保密保护和服务器身份验证 + @Override + public String[] getDefaultCipherSuites() { + return delegate.getDefaultCipherSuites(); + } + + // 返回的密码套件可用于SSL连接启用的名字 + @Override + public String[] getSupportedCipherSuites() { + return delegate.getSupportedCipherSuites(); + } + + + @Override + public Socket createSocket(final Socket socket, final String host, final int port, + final boolean autoClose) throws IOException { + final Socket underlyingSocket = delegate.createSocket(socket, host, port, autoClose); + return overrideProtocol(underlyingSocket); + } + + + @Override + public Socket createSocket(final String host, final int port) throws IOException { + final Socket underlyingSocket = delegate.createSocket(host, port); + return overrideProtocol(underlyingSocket); + } + + @Override + public Socket createSocket(final String host, final int port, final InetAddress localAddress, + final int localPort) throws + IOException { + final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort); + return overrideProtocol(underlyingSocket); + } + + @Override + public Socket createSocket(final InetAddress host, final int port) throws IOException { + final Socket underlyingSocket = delegate.createSocket(host, port); + return overrideProtocol(underlyingSocket); + } + + @Override + public Socket createSocket(final InetAddress host, final int port, final InetAddress localAddress, + final int localPort) throws + IOException { + final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort); + return overrideProtocol(underlyingSocket); + } + + private Socket overrideProtocol(final Socket socket) { + if (!(socket instanceof SSLSocket)) { + throw new RuntimeException("An instance of SSLSocket is expected"); + } + //((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"}); + ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"}); + return socket; + } + } +} diff --git a/common/src/main/java/ink/wgink/common/rpc/rest/request/RestRemoteRequest.java b/common/src/main/java/ink/wgink/common/rpc/rest/request/RestRemoteRequest.java index c57f0271..0f9a9aba 100644 --- a/common/src/main/java/ink/wgink/common/rpc/rest/request/RestRemoteRequest.java +++ b/common/src/main/java/ink/wgink/common/rpc/rest/request/RestRemoteRequest.java @@ -11,16 +11,12 @@ import org.slf4j.LoggerFactory; import org.springframework.http.*; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; -import javax.net.ssl.*; import java.lang.reflect.Type; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Map; @@ -37,45 +33,19 @@ import java.util.Map; public class RestRemoteRequest { private static final Logger LOG = LoggerFactory.getLogger(RestRemoteRequest.class); - private RestTemplate restTemplate; - - static { - try { - trustAllHttpsCertificates(); - HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { - public boolean verify(String urlHostName, SSLSession session) { - return true; - } - }); - } catch (Exception e) { - } - } - - private static void trustAllHttpsCertificates() throws NoSuchAlgorithmException, KeyManagementException { - TrustManager[] trustAllCerts = new TrustManager[1]; - trustAllCerts[0] = new TrustAllManager(); - SSLContext sc = SSLContext.getInstance("SSL"); - sc.init(null, trustAllCerts, null); - HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - } - - private static class TrustAllManager implements X509TrustManager { - public X509Certificate[] getAcceptedIssuers() { - return null; - } - - public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException { - } - - public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException { - } - } + private RestTemplate httpTemplate; + private RestTemplate httpsTemplate; public RestRemoteRequest() { HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); httpComponentsClientHttpRequestFactory.setConnectTimeout(20 * 1000); httpComponentsClientHttpRequestFactory.setReadTimeout(60 * 1000); - this.restTemplate = new RestTemplate(httpComponentsClientHttpRequestFactory); + this.httpTemplate = new RestTemplate(httpComponentsClientHttpRequestFactory); + + HttpsClientRequestFactory httpsClientRequestFactory = new HttpsClientRequestFactory(); + httpsClientRequestFactory.setConnectTimeout(20 * 1000); + httpsClientRequestFactory.setReadTimeout(60 * 1000); + this.httpsTemplate = new RestTemplate(httpsClientRequestFactory); } public Object request(RequestMethod requestMethod, String remoteUri, Map headers, MultiValueMap formVariableParams, Object jsonBody, Type resultType) { @@ -110,7 +80,7 @@ public class RestRemoteRequest { public String get(String remoteUri, Map headers) { try { HttpEntity httpEntity = getHttpEntity(headers, null, null); - ResponseEntity responseEntity = restTemplate.exchange(remoteUri, HttpMethod.GET, httpEntity, String.class); + ResponseEntity responseEntity = getRestTemplate(remoteUri).exchange(remoteUri, HttpMethod.GET, httpEntity, String.class); return getStringResponse(responseEntity); } catch (Exception e) { return getErrorResponse(e); @@ -127,7 +97,7 @@ public class RestRemoteRequest { public String delete(String remoteUri, Map headers) { try { HttpEntity httpEntity = getHttpEntity(headers, null, null); - ResponseEntity responseEntity = restTemplate.exchange(remoteUri, HttpMethod.DELETE, httpEntity, String.class); + ResponseEntity responseEntity = getRestTemplate(remoteUri).exchange(remoteUri, HttpMethod.DELETE, httpEntity, String.class); return getStringResponse(responseEntity); } catch (Exception e) { return getErrorResponse(e); @@ -144,7 +114,7 @@ public class RestRemoteRequest { public String post(String remoteUri, Map headers, Object jsonBody) { try { HttpEntity httpEntity = getHttpEntity(headers, null, jsonBody); - ResponseEntity responseEntity = restTemplate.exchange(remoteUri, HttpMethod.POST, httpEntity, String.class); + ResponseEntity responseEntity = getRestTemplate(remoteUri).exchange(remoteUri, HttpMethod.POST, httpEntity, String.class); return getStringResponse(responseEntity); } catch (Exception e) { return getErrorResponse(e); @@ -161,7 +131,7 @@ public class RestRemoteRequest { public String post(String remoteUri, Map headers, MultiValueMap formVariableParams) { try { HttpEntity httpEntity = getHttpEntity(headers, formVariableParams, null); - ResponseEntity responseEntity = restTemplate.exchange(remoteUri, HttpMethod.POST, httpEntity, String.class); + ResponseEntity responseEntity = getRestTemplate(remoteUri).exchange(remoteUri, HttpMethod.POST, httpEntity, String.class); return getStringResponse(responseEntity); } catch (Exception e) { return getErrorResponse(e); @@ -178,7 +148,7 @@ public class RestRemoteRequest { public String put(String remoteUri, Map headers, Object jsonBody) { try { HttpEntity httpEntity = getHttpEntity(headers, null, jsonBody); - ResponseEntity responseEntity = restTemplate.exchange(remoteUri, HttpMethod.PUT, httpEntity, String.class); + ResponseEntity responseEntity = getRestTemplate(remoteUri).exchange(remoteUri, HttpMethod.PUT, httpEntity, String.class); return getStringResponse(responseEntity); } catch (Exception e) { return getErrorResponse(e); @@ -266,4 +236,19 @@ public class RestRemoteRequest { throw new RemoteRequestException(e.getMessage(), e); } + /** + * 获取resttemplate模板 + * + * @param url + * @return + */ + private RestTemplate getRestTemplate(String url) { + if (StringUtils.startsWithIgnoreCase(url, "http://")) { + return this.httpTemplate; + } else if (StringUtils.startsWithIgnoreCase(url, "https://")) { + return this.httpsTemplate; + } + throw new RemoteRequestException("schema error, only support http(s)"); + } + }