Ich versuche herauszufinden, wie man eine erfolgreiche HTTP-GET-Anfrage an einen Server sendet, der SNI benötigt.Wie SNI in HTTP-Anfrage mit Apache HTTPComponents HttpClient aktivieren?
Ich suchte auf SO und anderen Orten und fand einige Artikel, die sagten, dass SNI jetzt in JDK7, sowie Apache HTTP-Komponenten unterstützt wird.
https://issues.apache.org/jira/browse/HTTPCLIENT-1119 https://wiki.apache.org/HttpComponents/SNISupport
Relevante SO Artikel: Certificate chain different between HTTPSURLconnection and Apache (System) DefaultHttpClient
-
Allerdings kann ich nicht scheinen, alle Dokumente zu finden, die zeigen, wie diese Arbeit zu bekommen. Hier
ist der Code, ich verwende ...
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
String trustedCertsPath = System.getenv("JAVA_HOME") + "/jre/lib/security/cacerts";
FileInputStream certstream = new FileInputStream(new File(trustedCertsPath));
try {
trustStore.load(certstream, "changeit".toCharArray());
} finally {
certstream.close();
}
// Trust own CA and all self-signed certs
SSLContext sslcontext = SSLContexts.custom()
.loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext,
new String[] { "TLSv1" },
null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient2 = HttpClients.custom()
.setSSLSocketFactory(sslsf)
.build();
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet(uri);
CloseableHttpResponse response = httpclient.execute(httpget);
try {
HttpEntity entity = response.getEntity();
if (entity != null) {
tempFile = File.createTempFile(httpFile.getTempFilePrefix(), httpFile.getTempFilePosfix());
FileOutputStream os = new FileOutputStream(tempFile);
InputStream instream = entity.getContent();
try {
IOUtils.copy(instream, os);
} finally {
try { instream.close(); } catch (Exception e) {}
try { os.close(); } catch (Exception e) {}
}
}
} finally {
response.close();
}
Wenn ich dies ausführen, schlägt die Anforderung fehl.
Der Server erfordert SNI in der Anforderung, und ohne sie gibt es ein abgelaufenes Cert zurück, das den falschen CommonName hat, aufgrund dessen es zurückgewiesen wird.
Wenn ich die Instanz httpclient2 verwende, die mit einem benutzerdefinierten SSL-Kontext eingerichtet wird, um alle HTTPS zuzulassen, ist die Anforderung erfolgreich. Dies möchte ich jedoch nicht auf einem Server aktivieren, der viele Downloads pro Tag gegen verschiedene Hosts durchführt.
Ich bin mit Httpclient v 4.3.5
Jede Hilfe sehr geschätzt.
Danke.
ich den Code durch Maven ausgeführt wird. Obwohl java7 jre auf dem Weg war und es ermöglichte, nahm maven immer noch den alten jre auf. Ich weiß nicht warum. Als ich den Code in eine separate Klasse isoliert und über jre7 ausgeführt habe, hat es funktioniert. – feroze