21

URLFetchサービスを使用して、Google App Engine アプリでHTTPS接続を開きたいと考えています。アプリが通信しているサーバーの 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 をサポートしているようですが、キーストアはカスタマイズできません。これは正しいです?

これが不可能な場合、そのアプローチは一般的に有効ですか? または、SSL 証明書を検証できる別の方法はありますか?

アップデート

2009 年、Google の App Engine 開発者 Nick Johnson はhttps://groups.google.com/d/topic/google-appengine-python/C9RSDGeIraE/discussionで次のように述べました。

urlfetch API では、独自のクライアント証明書を指定することはできないため、残念ながら現在のところ、目的を達成することはできません。

これはまだ正しいですか?App Engine のすべての HTTP(s) リクエストが URLFetch に依存している場合、これはカスタム証明書を GAE でまったく使用できないことを意味します。

4

4 に答える 4

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());

しかし、何らかの理由で、または別のアプリ エンジンがそれをブロックしません。

于 2015-04-29T17:10:34.583 に答える
3

アウトバウンド ソケット サポートの Trusted Testerとしてサインアップする必要があります。必要な機能の下で、SSL を登録します。JDK SSL API のより多くの部分がサポートされていれば、このようなものを構築するのは簡単です。

于 2012-12-07T16:01:16.993 に答える
0

同様の問題が発生しました...keystore.p12外部のWebサービスを呼び出す必要がありましたが、クラスパスからロードする機会がありませんでした。私がそれを使うことができた唯一の方法は、例えばそれを入れて、/WEB-INF/keystore.p12そこからそれをロードすることでした。

ServletContext context = getContext();
URL resourceUrl = context.getResource("/WEB-INF/keystore.p12");
于 2012-12-04T19:55:08.147 に答える