From 861da0da6f4246dedb293f6f5505aeda1015c33c Mon Sep 17 00:00:00 2001 From: egan Date: Sat, 23 Sep 2017 23:05:00 +0800 Subject: [PATCH] =?UTF-8?q?HTTPS=20SSL=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pay/common/http/HttpConfigStorage.java | 27 ++++ .../pay/common/http/HttpRequestTemplate.java | 130 ++++++++++++++---- .../egzosn/pay/demo/entity/ApyAccount.java | 23 ++++ .../egzosn/pay/demo/service/PayResponse.java | 14 +- pom.xml | 119 +++++++--------- 5 files changed, 206 insertions(+), 107 deletions(-) diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpConfigStorage.java b/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpConfigStorage.java index 8bc93f0..2aca267 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpConfigStorage.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpConfigStorage.java @@ -19,6 +19,11 @@ public class HttpConfigStorage { //代理密码 protected String httpProxyPassword; + //https请求所需的证书(PKCS12)地址,请使用绝对路径 + private String keystorePath; + //证书对应的密码 + private String storePassword; + /** * http代理地址 @@ -68,5 +73,27 @@ public class HttpConfigStorage { this.httpProxyPassword = httpProxyPassword; } + /** + * https请求所需的证书(PKCS12)地址,请使用绝对路径 + * @return 证书(PKCS12)地址 + */ + public String getKeystorePath() { + return keystorePath; + } + public void setKeystorePath(String keystorePath) { + this.keystorePath = keystorePath; + } + + /** + * 证书对应的密码 + * @return 密码 + */ + public String getStorePassword() { + return storePassword; + } + + public void setStorePassword(String storePassword) { + this.storePassword = storePassword; + } } diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpRequestTemplate.java b/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpRequestTemplate.java index 1043fb1..7f16509 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpRequestTemplate.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/http/HttpRequestTemplate.java @@ -7,21 +7,27 @@ import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.conn.ssl.DefaultHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; - +import org.apache.http.ssl.SSLContexts; +import javax.net.ssl.SSLContext; +import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.net.URI; +import java.security.*; import java.util.Map; /** * http请求工具 * @author: egan - *
- * email egzosn@gmail.com
+ *  
+ * email egzosn@gmail.com 
* date 2017/3/3 21:33 - *
+ * */ public class HttpRequestTemplate { @@ -29,6 +35,10 @@ public class HttpRequestTemplate { protected HttpHost httpProxy; + /** + * 获取代理带代理地址的 HttpHost + * @return 获取代理带代理地址的 HttpHost + */ public HttpHost getHttpProxy() { return httpProxy; } @@ -37,6 +47,10 @@ public class HttpRequestTemplate { return httpClient; } + /** + * 初始化 + * @param configStorage 请求配置 + */ public HttpRequestTemplate(HttpConfigStorage configStorage) { setHttpConfigStorage(configStorage); } @@ -45,39 +59,92 @@ public class HttpRequestTemplate { setHttpConfigStorage(null); } + + /** + * 创建ssl配置 + * @param configStorage 请求配置 + * @return SSLConnectionSocketFactory Layered socket factory for TLS/SSL connections. + */ + public SSLConnectionSocketFactory createSSL( HttpConfigStorage configStorage){ + + if (StringUtils.isEmpty(configStorage.getKeystorePath()) || StringUtils.isEmpty(configStorage.getKeystorePath())){ + return null; + } + + //读取本机存放的PKCS12证书文件 + try(FileInputStream instream = new FileInputStream(new File(configStorage.getKeystorePath()))){ + //指定读取证书格式为PKCS12 + KeyStore keyStore = KeyStore.getInstance("PKCS12"); + + char[] password = configStorage.getStorePassword().toCharArray(); + //指定PKCS12的密码 + keyStore.load(instream, password); + SSLContext sslcontext = SSLContexts.custom() + .loadKeyMaterial(keyStore, password).build(); + + //指定TLS版本 + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( + sslcontext, new String[]{"TLSv1"}, null, + new DefaultHostnameVerifier()); + + return sslsf; + } catch (IOException e) { + e.printStackTrace(); + } catch (GeneralSecurityException e) { + e.printStackTrace(); + } + return null; + + } + + /** + * 创建代理服务器 + * @param configStorage 请求配置 + * @return 代理服务器配置 + */ + public CredentialsProvider createProxy(HttpConfigStorage configStorage){ + + if (StringUtils.isBlank(configStorage.getHttpProxyHost())) { + return null; + } + //http代理地址设置 + httpProxy = new HttpHost(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()); + + if (StringUtils.isNotBlank(configStorage.getHttpProxyHost())) { + return null; + } + + // 需要用户认证的代理服务器 + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials( + new AuthScope(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()), + new UsernamePasswordCredentials(configStorage.getHttpProxyUsername(), configStorage.getHttpProxyPassword())); + + + return credsProvider; + } + /** * 设置HTTP请求的配置 + * * @param configStorage 请求配置 * @return 当前HTTP请求的客户端模板 */ - public HttpRequestTemplate setHttpConfigStorage(HttpConfigStorage configStorage){ + public HttpRequestTemplate setHttpConfigStorage(HttpConfigStorage configStorage) { - if (null == configStorage){ + if (null == configStorage) { httpClient = HttpClients.createDefault(); return this; } + httpClient = HttpClients + .custom() + //设置代理 + .setDefaultCredentialsProvider(createProxy(configStorage)) + //设置httpclient的SSLSocketFactory + .setSSLSocketFactory(createSSL(configStorage)) + .build(); - if (StringUtils.isNotBlank(configStorage.getHttpProxyHost())) { - // 使用代理服务器 - if (StringUtils.isNotBlank(configStorage.getHttpProxyUsername())) { - // 需要用户认证的代理服务器 - CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials( - new AuthScope(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()), - new UsernamePasswordCredentials(configStorage.getHttpProxyUsername(), configStorage.getHttpProxyPassword())); - httpClient = HttpClients - .custom() - .setDefaultCredentialsProvider(credsProvider) - .build(); - } else { - // 无需用户认证的代理服务器 - httpClient = HttpClients.createDefault(); - } - httpProxy = new HttpHost(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort()); - } else { - httpClient = HttpClients.createDefault(); - } return this; } @@ -132,10 +199,13 @@ public class HttpRequestTemplate { * @param 响应类型 * @return 类型对象 * - * Map<String, String> uriVariables = new HashMap<String, String>(); - * uriVariables.put("id", "1"); - * uriVariables.put("type", "APP"); - * getForObject("http://egan.in/pay/{id}/f/{type}", String.class, uriVariables) + * Map<String, String> uriVariables = new HashMap<String, String>();
+ * + * uriVariables.put("id", "1");
+ * + * uriVariables.put("type", "APP");
+ * + * getForObject("http://egan.in/pay/{id}/f/{type}", String.class, uriVariables)
*
*/ public T getForObject(String uri, Class responseType, Map uriVariables){ diff --git a/pay-java-demo/src/main/java/com/egzosn/pay/demo/entity/ApyAccount.java b/pay-java-demo/src/main/java/com/egzosn/pay/demo/entity/ApyAccount.java index 09fc1f2..a8f5ad0 100644 --- a/pay-java-demo/src/main/java/com/egzosn/pay/demo/entity/ApyAccount.java +++ b/pay-java-demo/src/main/java/com/egzosn/pay/demo/entity/ApyAccount.java @@ -40,6 +40,13 @@ public class ApyAccount { // 收款账号 // @Column(name = "seller") private String seller; + + //请求证书地址,请使用绝对路径 + private String keystorePath; + //证书对应的密码 + private String storePassword; + + // 签名类型 // @Column(name = "sign_type") private String signType; @@ -156,6 +163,22 @@ public class ApyAccount { return isTest; } + public String getKeystorePath() { + return keystorePath; + } + + public void setKeystorePath(String keystorePath) { + this.keystorePath = keystorePath; + } + + public String getStorePassword() { + return storePassword; + } + + public void setStorePassword(String storePassword) { + this.storePassword = storePassword; + } + public void setTest(boolean test) { isTest = test; } diff --git a/pay-java-demo/src/main/java/com/egzosn/pay/demo/service/PayResponse.java b/pay-java-demo/src/main/java/com/egzosn/pay/demo/service/PayResponse.java index 49f45fd..e1ae7da 100644 --- a/pay-java-demo/src/main/java/com/egzosn/pay/demo/service/PayResponse.java +++ b/pay-java-demo/src/main/java/com/egzosn/pay/demo/service/PayResponse.java @@ -57,12 +57,14 @@ public class PayResponse { } /** - * 获取http配置,如果配置为null则为默认配置,无代理。 - * 此处非必需 - * @return + * 获取http配置,如果配置为null则为默认配置,无代理,无证书的请求方式。 + * 此处非必需 + * @param apyAccount 账户信息 + * @return 请求配置 */ - public HttpConfigStorage getHttpConfigStorage(){ + public HttpConfigStorage getHttpConfigStorage(ApyAccount apyAccount){ HttpConfigStorage httpConfigStorage = new HttpConfigStorage(); + /* //http代理地址 httpConfigStorage.setHttpProxyHost("192.168.1.69"); //代理端口 @@ -71,6 +73,10 @@ public class PayResponse { httpConfigStorage.setHttpProxyUsername("user"); //代理密码 httpConfigStorage.setHttpProxyPassword("password"); + + */ + httpConfigStorage.setKeystorePath(apyAccount.getKeystorePath()); + httpConfigStorage.setStorePassword(apyAccount.getStorePassword()); return httpConfigStorage; } diff --git a/pom.xml b/pom.xml index 6d06e79..a53b228 100644 --- a/pom.xml +++ b/pom.xml @@ -103,74 +103,18 @@ https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - release - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - - attach-javadocs - - jar - - - - - UTF-8 - zh_CN - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - - - - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.17 - - - - + org.apache.maven.plugins + maven-compiler-plugin + + 1.7 + 1.7 + utf-8 + + + \ No newline at end of file