任何人都可以帮助我开始在Java中执行带有服务器名称指示的HTTP连接吗?
我正在尝试从我管理的网站请求内容。我一直在使用Apache的HttpClient库,但我对安全内容的请求失败,因为网站仅使用SNI进行HTTPS,并且在DefaultHttpClient中未启用SNI。我已经在Apache的HttpClient库中查找了如何处理这个问题的说明,但是最终我看到了这个文档:http://hc.apache.org/httpclient-3.x/sslguide.html,它已经过时了(当HttpClient和HttpCore是Apache的公共部分时,指的是代码)封装)。
那么......任何帮助?
答案 0 :(得分:11)
您可能想跟踪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被修复
答案 1 :(得分:5)
这是我在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();
答案 2 :(得分:1)
使用如下所述的简短修复程序: TLS with SNI in Java clients 可以将SNI服务器支持添加到JDK 7并将其与X509ExtendedKeyManager一起使用。
答案 3 :(得分:1)
对我来说有用的是在Apache配置中正确配置ServerName
:
/etc/apache2/sites-avaible/default
<VirtualHost *:443>
ServerName foo.domain.com
...
</VirtualHost>
答案 4 :(得分:0)
此问题似乎已在Java 7中修复。