誰かがJavaでサーバー名を表示してHTTP接続を始めるのを手伝ってくれる?
管理しているサイトからコンテンツをリクエストしようとしています。 ApacheのHttpClientライブラリを使用していますが、WebサイトがHTTPSにSNIのみを使用しており、DefaultHttpClientでSNIが有効になっていないため、安全なコンテンツのリクエストが失敗します。 ApacheのHttpClientライブラリ内でこれにアプローチする方法についての説明を探しましたが、最終的にはこのドキュメントが表示されます: http://hc.Apache.org/httpclient-3.x/sslguide.html =、これは古くなっています(HttpClientとHttpCoreがApacheのcommonsパッケージの一部であったときのコードバックを参照しています)。
それで...何か助けはありますか?
あなたは追跡したいかもしれません https://issues.Apache.org/jira/browse/HTTPCLIENT-1119
Java 7の基礎となるクライアント実装はそれをサポートでき、SSLSocketImpl#setHost(Sun.net.www.protocol.https.HttpsClientによって呼び出されます)を介して機能を公開します
Java 7使用
new URL("https://cmbntr.sni.velox.ch/").openStream()
hTTPCLIENT-1119が修正されるまで
これは私がorg.Apache.httpcomponentsのhttpclient v4.3 +でそれをした方法です
private HttpClientConnectionManager createConnectionManager(final SSLContext ctx) {
LOG.info("Creating sslConnectionSocketFactory");
final SSLConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(ctx) {
@Override
protected void prepareSocket(SSLSocket socket) throws IOException {
try {
System.out.println("************ setting socket Host property *************");
PropertyUtils.setProperty(socket, Host, Constants.SNI_Host);
} catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException ex) {
LOG.error(ex.getMessage());
}
super.prepareSocket(socket);
}
};
LOG.info("Creating connectionRegistry");
final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslSF)
.build();
LOG.info("Creating poolingConnectionManager");
final PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
connectionManager.setDefaultMaxPerRoute(MAX_CONNECTIONS_PER_ROUTE);
connectionManager.setMaxTotal(MAX_CONNECTIONS);
return connectionManager;
}
そして、これが私がHttpClient
を作成した方法です
final KeyManager[] keyManagers = createKeyManagers();
final TrustManager[] trustManagers = createTrustManagers();
final SSLContext ctx = createSslContext(keyManagers, trustManagers);
final HttpClientConnectionManager connectionManager = createConnectionManager(ctx);
LOG.info("Creating httpClient");
HttpClient httpClient = HttpClients
.custom()
.setConnectionManager(connectionManager)
.build();
以下で説明する短い修正を加えてください。 TLS in SNI with Java clients SNIサーバーサポートをJDK 7に追加し、X509ExtendedKeyManagerと一緒に使用することが可能です。
私にとってうまくいったのは、Apache構成でServerName
を正しく構成することでした。
/etc/Apache2/sites-avaible/default
<VirtualHost *:443>
ServerName foo.domain.com
...
</VirtualHost>
この問題は Java 7 で修正されたようです。