Quelqu'un peut-il m'aider à commencer à établir des connexions HTTP avec indication du nom du serveur en Java?
J'essaie de demander du contenu à un site que je suis en train d'administrer. J'utilise la bibliothèque HttpClient d'Apache, mais ma demande de contenu sécurisé échoue car le site Web utilise uniquement SNI pour HTTPS, et SNI n'est pas activé dans le DefaultHttpClient. J'ai cherché des instructions sur la façon d'aborder cela dans la bibliothèque HttpClient d'Apache, mais je vois que je vais finir avec ce document: http://hc.Apache.org/httpclient-3.x/sslguide.html , qui est obsolète (référence au code à l'époque où HttpClient et HttpCore faisaient partie du paquetage commun d'Apache).
Alors ... de l'aide?
vous voudrez peut-être suivre https://issues.Apache.org/jira/browse/HTTPCLIENT-1119
l'implémentation client sous-jacente de Java 7 est capable de la prendre en charge et expose la fonctionnalité via SSLSocketImpl # setHost (appelée par Sun.net.www.protocol.https.HttpsClient
sur l'utilisation de Java 7
new URL("https://cmbntr.sni.velox.ch/").openStream()
jusqu'à ce que HTTPCLIENT-1119 soit corrigé
Voici comment je l'ai fait dans httpclient v4.3 + d'org.Apache.httpcomponents
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;
}
Et voici comment j’ai créé le 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();
avec un correctif court comme décrit dans: TLS avec SNI dans les clients Java Il est possible d’ajouter la prise en charge du serveur SNI à JDK 7 et de l’utiliser conjointement avec X509ExtendedKeyManager.
Ce qui a fonctionné pour moi, c’est de configurer correctement la ServerName
dans la configuration d’Apache:
/etc/Apache2/sites-avaible/default
<VirtualHost *:443>
ServerName foo.domain.com
...
</VirtualHost>
Comme indiqué dans https://stackoverflow.com/a/8058839/2088282 .
Il semble que ce problème soit résolu dans Java 7 .