2012-06-07 24 views
16

我們需要在Google App Engine上實現雙向SSL,在這種情況下,我們使用JAX-WS將Web服務請求發送到服務器,以請求雙向SSL身份驗證。用於GAE上的Web服務的雙向SSL(java)

如何爲我們的傳出Web服務請求設置雙向SSL?

我們知道javax.net.ssl*在App Engine環境中是被禁止的。

這裏是我們的代碼示例:或

ListenerSoap soap = new Listener().getListenerSoap(); 
soap.ping(); 

我想我們可以存儲密鑰庫中所需要的任何證書:

@WebService(name="ListenerSoap", targetNamespace = "http://example.com/Listener.Wsdl") 
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE) 
public interface ListenerSoap { 

    @WebMethod(operationName = "Ping", action="http://example.com/Listener.Wsdl#Ping") 
    public void ping(); 
} 

@WebServiceClient(name="Listener", targetNamespace="http://example.com/Listener.Wsdl", wsdlLocation = "https://example.com/Listener.asmx?WSDL") 
public class Listener extends Service 
{ 
    public ListenerSoap getListenerSoap() { 
    return super.getPort(new QName("http://example.com/Listener.Wsdl", 
         "ListenerSoap"), ListenerSoap.class); 
    } 
} 

而在使用上面的代碼示例DataStore作爲二進制對象(儘管如何上傳它們對我來說仍然是一個小小的模糊)。

我們該如何設置此Web服務使用雙向SSL進行身份驗證所需的必要值?

感謝所有幫助

更新:

通過我已經看到了這個研究是如何能在傳統的服務器上完成(一個與文件系統訪問):

ListenerSoap soap = new Listener().getListenerSoap(); 
((BindingProvider) soap).getRequestContext().put("javax.net.ssl.keyStore", "client_cert.p12" 

但是,在這種方法中,client_cert.p12預計在文件系統上。

此外,SSLSocketFactorySSLContextKeyManagerKeyManagerFactory都不允許在GAE上。

更新:

由於GAE SDK版本1.7.7。現在應該是可能的:

Similarly, Java developers can now use the javax.net.ssl package to make outbound SSL connections. 

GAE 1.7.7 SDK Release Notes

+6

在URLFetch服務中有一個支持客戶端證書的開放功能請求:http://code.google.com/p/googleappengine/issues/detail?id=3719 –

回答

0

什麼,我知道的雙向SSL,你將不得不使用Java EE代碼沒有鏈接:雙向SSL是傳輸層安全:當你的客戶端應用程序將嘗試與服務器創建安全的HTTP連接(HTTPS),服務器將要求提供證書並且將批准或不批准此證書。如果客戶端證書被批准,那麼將在各方建立安全連接,並允許他們通過該隧道交換一些消息。但是這個過程是在傳輸層完成的。您的代碼(在應用程序層)永遠不會被通知這個過程。 爲了建立雙向SSL,安裝程序在SSL端口的應用程序服務器設置上完成。

+4

這絕對是不正確的。完全可以通過應用程序代碼建立雙向SSL連接,例如設置'systemProps.put(「javax.net.ssl.keyStore」,keyStorePath)''。問題是GAE將'java.net.ssl *'軟件包列入黑名單,所以在撰寫本文時,不可能在GAE上這樣做。 – Cuga

+0

我應該承認我錯了。這裏有一個關於如何在java代碼中實現雙向SSL的簡單代碼:https://sites.google.com/site/ssljavaguide/example-code/2-way-ssl – omartin

+0

這仍然不能在GAE上工作,因爲所有類被列入'javax.net.ssl。*'包的黑名單,包括'SSLSocket'和'SSLSocketFactory' – Cuga

1
ListenerSoap soap = new Listener().getListenerSoap(); 

希望它改善

感謝

+0

是的,甚至包括在帖子中......問題是如何獲得雙向SSL在GAE- - 看起來不可行的任務。 – Cuga

1

我知道你可能不希望聽到這一點,但使用SSL是昂貴和有問題的雙向通信。根據您對服務器/客戶端的控制權限,我更喜歡簡單的雙向管道,如Web套接字和可以簡單實現AES的數據包協議。這真的取決於你正在試圖解決的問題。

+2

我認爲OP正在談論雙向授權*(實際上是認證)。 –

+0

並且一旦通過驗證? –

+1

*通信*在兩個方向都是安全的;公鑰/私鑰用於交換雙方用於加密的對稱密鑰。這個問題是關於在*客戶*和*服務器上使用證書來驗證每個證書。 –

1

聽起來好像對通過SSL(https://...)的簡單連接和所謂的「相互認證」或「公鑰基礎結構(PKI)」存在混淆。你實際上可以做兩個或一個獨立於另一個。對於後者(我認爲原始問題所指的是),當您向服務器發出請求時,服務器會回覆您,要求您提供一份證書,以證明您自己。

要回答上面的具體問題(從二進制數據加載密鑰庫),我不認爲這是真的可能,因爲它是在您的密鑰庫中啓動的Java運行時。你唯一能想到的就是從你的數據存儲中加載這些位並暫時寫入磁盤。可選擇在應用程序存在時將其刪除。這我以前做過,工作得很好。如果你這樣做,我推薦使用可能是可寫的位置(如System.getProperty("java.io.tmpdir"));),然後將文件寫入到磁盤後,將JVM屬性(如System.getProperties().put("javax.net.ssl.keyStore","...");

+0

另一種選擇(如果你不能寫入磁盤或使用javax.net.ssl。*)是手動執行連接(即使用Apache HTTP Client),以添加一個密鑰庫。然後,您只需定期HTTP POST到端點並解析響應。請參閱:http://stackoverflow.com/questions/5206010/using-apache-httpclient-for-https –

+0

正如原始文章的更新中所提到的,不可能在GAE上設置'javax.net.ssl',因爲這些軟件包的黑名單。寫入任何文件磁盤也是不可能的。我們已經在使用它的其他服務器上設置了PKI,但GAE不會允許它。 – Cuga

+0

明白了。我對GAE並不熟悉。看起來你唯一的選擇就是不使用JAX-WS代碼,而是使用像Apache HTTPClient這樣稍低一些的設置,你可以在其中設置所有的安全信息。這並不美觀,但我已經使用Velocity之類來模擬SOAP消息,並使用Apache HC將其發佈到服務器。缺點是你必須手動解析響應(沒有用JAX-WS生成的代碼得到的花哨的POJO映射)。 –

2

從我對SSL的授權限制的知識,看來你可能會丟失在這裏至關重要的東西;證書。雙向SSL需要客戶端和服務器證書在您的密鑰庫中,這可以是自簽名證書(pkcs12或pem文件,您可以通過shell通過幾條命令輕鬆生成)或由像Thawte或Verisign這樣的授權公司。 儘管我不確定這是否是您所面臨的問題,但它很適合檢查。 (另外,我是一個新手,所以請不要downvote我的答案,只是試圖建議可能的選項。)

+1

謝謝。我們擁有所有的鑰匙和證書。問題是能夠在GAE環境中提供證書,這在當時是不可能的,但今天看起來像Google最近的白名單有可能。 – Cuga

1

不支持雙向SSL(從GAE託管應用程序到外部世界),至於我知道。我在幾個月前嘗試過一個示例應用程序,並且很失望地發現GAE甚至不支持這個基本功能。並且文檔也不清楚。當您聯繫網絡服務時,您將無法提供客戶端證書..無法存儲它,密鑰庫無法訪問。

+0

我還沒有嘗試過,但是從GAE SDK v1.7.7開始,現在可能會這樣做,因爲他們已將白名單列入'javax.net.ssl'包,現在應該讓我們指定cert via '((BindingProvider)soap).getRequestContext()。put(「javax.net.ssl.keyStore」... ...' – Cuga