使用HttpClient攜帶pfx證書調用HTTPS協議的WebService


調用第三方服務時,廠商提供了一個WSDL文件、調用的地址和一個后綴為pfx的證書文件,通過SOUPUI記載證書是可以正常調用WebService服務,那么如何將該服務轉換為代碼呢?

咨詢了廠商的支持,廠商說直接發送報文即可。

觀察SOUPUI的調用發現直接發送的SOUP報文,那么決定使用HttpClient進行服務調用,調用HTTPS好說、發送報文也好說,關鍵問題卡在了pfx證書上面。

百度了很多例子,說JAVA無法直接攜帶pfx的證書,那么就在pfx證書轉換方面嘗試了一些,最終沒有轉換成功。

繼續觀察SOUPUI的調用模式,SOUPUI可以在PERFERENCE的SSL中可以直接配置keystore和password,就可以攜帶證書,而且SOUPUI調用各種服務主要是使用HTTPClient完成的的,他可以實現,那就說明通過HTTPClient是可以直接攜帶pfx格式的證書的,基本思路確定,那就全力在這條路上繼續折騰吧。

 

整理一下尷尬的情況:

資源:HTTPS協議、WebService服務、需要pfx證書認證;

目標:通過HttpClient構建SSL通道調用HTTPS的WebService接口,攜帶pfx證書信息,直接發送SOUP報文調用接口;

難點:pfx證書如何處理?

 

百度了好久,有相應的解決方案,但實驗后均不行;后在bing的國際版中進行搜索,結果中stackoverflow中有了大收獲。

地址:https://stackoverflow.com/questions/44493040/apache-httpclient-pfx-file

該國際友人碰到了和我一樣的問題,通過SOUPUI攜帶pfx證書調用Https的WebService服務沒有問題,使用HttpClient模擬報文的時候無法攜帶證書,但是該哥們自行解決了該問題,而且還無私的把源代碼整個貼在了論壇上,我用顫抖的雙手復制粘貼了該代碼,稍作修改執行發現問題解決。天哪,折騰了一個下午加晚上,終於算是解決了。

 

在此特意轉發一下這位大神的佳作:

KeyStore clientStore  = KeyStore.getInstance("PKCS12"); 
InputStream instream = Thread.currentThread().getContextClassLoader().getResourceAsStream(keystoreName);
try {
    clientStore.load(instream, keyStorePwd.toCharArray());
} finally {
    instream.close();
}
//Trust everybody
X509TrustManager tm = new X509TrustManager() {
    @Override
    public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws CertificateException {}
    @Override
    public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1) throws CertificateException {}
    @Override
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {return null;}
};
SSLContext sslCtx = SSLContext.getInstance("TLS");
KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmfactory.init(clientStore, keyStorePwd != null ? keyStorePwd.toCharArray() : null);
KeyManager[] keymanagers = kmfactory.getKeyManagers();
sslCtx.init(keymanagers, new TrustManager[]{tm}, null);
SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(sslCtx);
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create().register("https", sslConnectionFactory).register("http", new PlainConnectionSocketFactory()).build();
PoolingHttpClientConnectionManager pcm = new PoolingHttpClientConnectionManager(registry);
HttpClientBuilder hcb = HttpClientBuilder.create();
hcb.setConnectionManager(pcm);
CloseableHttpClient httpClient = hcb.build();


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM