文章出處

Axis 1.x 編寫的client在測試https的webservice的時候, 由于client 代碼建立SSL連接的時候沒有對truststore進行設置,在與https部署的webservice 連接會在運行時報出:

 javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

 

這是由于Axis的client用默認的SocketFactory,會對server端的證書進行驗證,我們的測試server是自簽名的,client檢測到后自動斷開連接,握手失敗。

網上很多解決方案是用sun的keytool生成clientTrustStore和serverTrustStrore并把證書導進去,這些方法都稍顯繁瑣,我們這種client測試類沒必要做一些程序之外的工作,所以綜合了一個解決方案,想到這個辦法。此方法的靈感來自于axis文檔里的dirty solution。

 

核心思想是自己做一個不對證書做任何檢查的SocketFactory,并用這個socket factory來替換Axis本身用的SocketFactory, 為了方便,MySocketFactory直接繼承Axis的父類JSSESocketFactory 。并且重寫父類方法

 protected void initFactory() throws IOException

 initFactory方法的內容,很簡單,就是讓checkServerTrusted/checkClientTrusted什么都不返回,然后最后一行將這個SslSocketFactory賦給我們自定義類里的sslFactory變量。


// Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { // Trust always } public void checkServerTrusted(X509Certificate[] certs, String authType) { // Trust always } } }; // Install the all-trusting trust manager SSLContext sc = SSLContext.getInstance("SSL"); // Create empty HostnameVerifier HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String arg0, SSLSession arg1) { return true; } }; sc.init(null, trustAllCerts, new java.security.SecureRandom());
  sslFactory = sc.getSocketFactory;

Axis client測試類中用

AxisProperties.setProperty("axis.socketSecureFactory","my.test.MySocketFactory")來指定Axis類庫要調用的SocketFactory,就是之前被我們改寫的不對server certificate做任何驗證的Factory。

 

這個解決方式絕對簡單,不需要跟其他方式一樣用sun的keytool建立導入一些本地證書,并利用了Axis自己的機制處理證書驗證問題。

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()