2012-10-24 46 views
20

我想使用URLFetch服務在Google App Engine應用程序中打開HTTPS連接。爲了能夠驗證我的應用正在與之交談的服務器的SSL證書,我正在使用我自己的密鑰庫文件。當我的應用程序被加載時,即在執行任何HTTPS請求之前,我想在warmup request中讀取此文件。密鑰庫文件是我的WAR文件的一部分。在Google App Engine Java應用程序中加載自定義密鑰存儲區

TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 
keystore.load(ClassLoader.getSystemResourceAsStream("myKeystoreFile"), "password".toCharArray()); 
trustManagerFactory.init(keystore); 

TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); 
SSLContext sslContext = SSLContext.getInstance("SSL"); 
sslContext.init(null, trustManagers, null); 

HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); 

我不能使用這種方法,但是,因爲雖然HttpURLConnection類是在GAE上的JRE白名單,HttpsURLConnection的是沒有的。

在GAE中是否有另一種使用自定義密鑰庫的方法?在GAE文檔中我沒有找到任何關於此的信息。 看起來像Google的URLFetch服務支持HTTPS,密鑰庫不能自定義。這是正確的嗎?

如果這是不可能的,該方法仍然有效嗎?或是否有一種不同的方法,仍然允許我驗證SSL證書?

UPDATE

2009年,谷歌App Engine的開發者尼克·約翰遜https://groups.google.com/d/topic/google-appengine-python/C9RSDGeIraE/discussion說:

的網址抓取API不會允許您指定自己的客戶端 證書,所以很遺憾你想實現的目前不是 。

這是否仍然正確?如果App Engine中的每個HTTP請求都依賴於URLFetch,則這意味着GAE中根本無法使用自定義證書。

+0

事實證明,[GAE的Google代碼網站](http://code.google.com/p/googleappengine/issues/detail?id=3719)存在未解決的問題。 – Ingo

+1

需要什麼才能在App Engine上支持此功能? ** Google的某人可以概述爲實現這個目的需要做些什麼嗎?** – Ingo

+0

Leviticus說他使用Apache HTTP客戶端實現了這一點,請參閱http://esxx.blogspot.com/2009/06/using-apaches- HttpClient的上,谷歌,app.html。我仍在試圖理解他的方法。有沒有人試過這個? 他把源代碼顛覆在這裏:http://svn.berlios.de/svnroot/repos/esxx/trunk/jee/org/esxx/js/protocol – Ingo

回答

0

我有類似的問題...我需要一個keystore.p12來調用外部Web服務,但沒有機會從類路徑加載它。我能夠使用它的唯一方法是將它放入例如/WEB-INF/keystore.p12並從那裏加載它。

ServletContext context = getContext(); 
URL resourceUrl = context.getResource("/WEB-INF/keystore.p12"); 
+0

也許它是一個Java政策問題。您是否編輯了策略文件並允許所有(作爲測試)? – djangofan

4

我最近面臨同樣的問題,並使用與appengine-api-stubs一起打包的HttpClient實現爲我工作。

Maven的相關性:

<dependency> 
    <groupId>com.google.appengine</groupId> 
    <artifactId>appengine-api-stubs</artifactId> 
    <version>1.9.18</version> 
</dependency> 

代碼:

// create SSL Context which trusts your self-signed certificate 
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); 
keystore.load(ClassLoader.getSystemResourceAsStream("myKeystoreFile"), "password".toCharArray()); 
trustManagerFactory.init(keystore); 
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); 
SSLContext sslContext = SSLContext.getInstance("SSL"); 
sslContext.init(null, trustManagers, null); 

// register your trusting SSL context 
Protocol.registerProtocol("https", 
     new Protocol("https", (ProtocolSocketFactory) new SocketFactoryWrapper(sslContext.getSocketFactory()), 443)); 

// make the https call 
HttpClient httpclient = new HttpClient(); 
GetMethod httpget = new GetMethod("https://myendpoint.com"); 
httpclient.executeMethod(httpget); 
System.out.println(httpget.getStatusLine()); 

這確實基本上是同樣的事情

HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); 

但由於某種原因App Engine不阻止它。

0

我使用的AppEngine API 56年9月1日,什麼迪馬與

Protocol.registerProtocol("https", 
    new Protocol("https", (ProtocolSocketFactory) new SocketFactoryWrapper(sslContext.getSocketFactory()), 443)); 

不工作了建議。因此我也不需要appengine-api-stubs庫。

但是,HttpsURLConnection.setDefaultSSLSocketFactory只是正常工作。

這是我這解決了我的問題完整的解決方案:

KeyStore keystore = KeyStore.getInstance("JKS"); 
    InputStream in = getClass().getResourceAsStream("/mytruststore.jks"); 
    keystore.load(in, "password".toCharArray()); 
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    trustManagerFactory.init(keystore); 
    TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); 
    SSLContext sslContext = SSLContext.getInstance("SSL"); 
    sslContext.init(null, trustManagers, null); 

    HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); 

幸運的是HttpsURLConnection不再被列入黑名單,因爲它是在問題發生的時間。

相關問題