2012-04-16 431 views
2

我有以下問題。我有一個webservice,它具有可以通過SSL調用的端點,還有一些只能通過使用客戶端證書來對客戶端進行身份驗證才能調用。問題是我想動態更改客戶端證書。 我的代碼是:Java web服務客戶端,動態更改客戶端證書

System.setProperty("javax.net.ssl.trustStore", "cacerts.jks"); 
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 
//... 
// first web service call, without client side certificate -> OK 
//... 
System.setProperty("javax.net.ssl.trustStore", "cacerts.jks"); 
System.setProperty("javax.net.ssl.trustStorePassword", "changeit"); 
System.setProperty("javax.net.ssl.keyStore", "keystore1.jks"); 
System.setProperty("javax.net.ssl.keyStoreType", "JKS"); 
System.setProperty("javax.net.ssl.keyStorePassword", "password"); 
//... 
// second web service call 

我的問題是在第二個電話。在這裏,我得到一個異常:

javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure 

如果我只運行的代碼一切的第二部分是好的,它完美的作品(所以我有 keystore.jks與客戶端證書,服務器做正確驗證我的請求)。我究竟做錯了什麼?如何在調用webservices時動態更改客戶端證書?

回答

3

我懷疑正在發生的事情是您正在使用某種方法將其默認JSSE SSLContext用於其SSL套接字工廠。從documentation看來,SSL上下文僅在首次創建時才配置一次,並且在第一次使用後設置系統屬性不起作用。

我推薦使用Apache HttpClient。他們的SSLSocketFactory實現允許編程定製密鑰庫和信任庫以用於與該工廠進行的連接。最重要的是,HttpClient爲您提供了比JDK提供的更多功能和配置選項。

+0

+1同意。 SSL上下文只被配置一次 – jaxb 2012-04-17 05:00:03

+0

我試圖使用他們的SSLSocketFactory,但它與'javax.net.ssl.SSLSocketFactory'不兼容。我得到一個'ClassCastException': 'org.apache.http.conn.ssl.SSLSocketFactory不能轉換爲javax.net.ssl.SSLSocketFactory' 那麼最簡單的方法是什麼? – hpityu 2012-04-17 11:16:56

+1

@hpityu您正在使用什麼庫來進行Web服務調用?您將無法將Apache'SSLSocketFactory'實例放置到需要'javax.net.ssl.SSLSocketFactory'的某個位置。它被設計用於Apache提供的'HttpClient'。根據您的應用程序,您可能(1)重寫您的客戶端代碼以使用'HttpClient',或者(2)編寫一個適配器來包裝Apache'SSLSocketFactory'以實現'javax.net.ssl.SSLSocketFactory'。 – Alex 2012-04-17 17:17:39