在Google App Engine Java应用程序中加载自定义密钥库
我想使用URLFetch服务在Google App Engine应用中打开HTTPS连接。 为了能够validation我的应用正在与之交谈的服务器的SSL证书,我使用自己的密钥库文件 。 我想在我的应用程序加载时,即在执行任何HTTPS请求之前,在预热请求中读取此文件。 密钥库文件是我的WAR文件的一部分。
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时,无法自定义密钥库。 它是否正确?
如果这是不可能的,那么这种方法一般是否仍然有效? 或者是否有一种不同的方法仍然允许我validationSSL证书?
UPDATE
2009年,谷歌的App Engine开发者Nick Johnson在https://groups.google.com/d/topic/google-appengine-python/C9RSDGeIraE/discussion上说:
urlfetch API不允许您指定自己的客户端证书,因此很遗憾您目前无法实现所需的目标。
这还是正确的吗? 如果App Engine中的每个HTTP(s)请求都依赖于URLFetch,这意味着GAE中根本无法使用自定义证书。
我最近面临同样的问题,使用与appengine-api-stubs打包在一起的HttpClient实现对我有用。
Maven依赖:
com.google.appengine appengine-api-stubs 1.9.18
码:
// 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());
但由于某种原因,应用程序引擎无法阻止它。
您应该注册为Outbound socket支持的可信测试人员 。 在Desired Features下,他们登记SSL。 如果支持JDK SSL API的更多部分,那么构建这样的东西会很简单。
我有一个类似的问题…我需要一个keystore.p12
来调用外部Web服务,但没有机会从类路径加载它。 我能够使用它的唯一方法是将它放在例如/WEB-INF/keystore.p12
并从那里加载它。
ServletContext context = getContext(); URL resourceUrl = context.getResource("/WEB-INF/keystore.p12");
我正在使用Appengine API 1.9.56以及Dima建议的内容
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
不再被列入黑名单,因为它是在提出问题的时候。
- 是否可以使用Java在Google App Engine上拥有计算属性?
- Google AppEngine中的JSP是否支持JDK1.8
- AppEnginePlugin:不支持的major.minor版本51.0 – appengine 1.9.17
- 从PDF中提取文字(谷歌应用引擎)
- 如何使用java在谷歌应用程序中编写csv文件
- GWT:在服务器端调用与客户端相同的RPC方法
- 如何在使用Google App Engine时关闭DataNucleus Enhancer
- 在Google App Engine JAVA中创建多个实例
- 会话超时(session.setMaxInactiveInterval)在Google Appengine中不起作用