Java上的服务器名称指示(SNI)
任何人都可以帮助我开始使用Java中的服务器名称指示执行HTTP连接吗?Java上的服务器名称指示(SNI)
我试图从我管理的网站请求内容。我一直在使用Apache的HttpClient库,但是我对安全内容的请求失败,因为该网站只使用SNI作为HTTPS,并且在DefaultHttpClient中未启用SNI。我一直在寻找关于如何在Apache的HttpClient库中处理这个问题的指导,但我最终看到这个文档:http://hc.apache.org/httpclient-3.x/sslguide.html,它已经过期(当HttpClient和HttpCore是Apache公共包的一部分时,指的是代码)。
那么......有什么帮助吗?
您可能需要跟踪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是固定
看来这个问题已在Java 7中修复。
感谢。我明白这是事实。但是,RFC并没有提供任何关于如何实现这一点的暗示(除非是从头开始构建自己的客户端)。任何想法的现有工具或如何使用Apache HttpClient的? – JellicleCat
什么工作对我来说是在Apache的配置正确配置ServerName
:
/etc/apache2/sites-avaible/default
<VirtualHost *:443>
ServerName foo.domain.com
...
</VirtualHost>
这是我如何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();
现在已经修复,可在HttpComponents HttpClient 4.3.2中找到。 –
在OpenJDK的Tomcat中使用HttpClient 4.3.2(最高版本为“1.7.0_111”),SNI仍会失败。切换到Oracle HotSpot('1.7.0_80')后,SNI工作。对于在AWS Beanstalk上面临此问题的任何人,请查看此ebextension以将JVM切换到Oracle:https://gist.github.com/bremeld/6706980 – Sitati