【发布时间】:2016-12-19 10:09:43
【问题描述】:
我在运行 Java 7 (Oracle JVM) 的 Tomcat 7 上部署了一个 Java webapp。
我对外部 HTTPS url 的所有 Apache HTTPClient 请求都失败了(仅在生产中),我不太清楚为什么。我检查了JVM自带的cacerts信任库,所有证书都是有效的。
我已将 JVM 和 Tomcat 目录下载到我的开发机器并运行了 webapp(使用相同的路径、相同的参数等)并且它可以工作。
执行在生产环境中发出 HTTPS 请求的独立 JAR 也可以。
坦率地说,在这一点上,我没有想法。
这是失败的示例代码:
InputStream is=null;
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 2000);
HttpConnectionParams.setSoTimeout(httpParams, 2000);
DefaultHttpClient httpclient = new DefaultHttpClient(httpParams);
try {
httpclient.getParams().setParameter("http.useragent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
HttpContext localContext = new BasicHttpContext();
HttpHead httphead = new HttpHead(url);
HttpResponse response = httpclient.execute(httphead, localContext);
HttpGet httpget = new HttpGet(url);
response = httpclient.execute(httpget, localContext);
HttpEntity entity = response.getEntity();
is= new ByteArrayInputStream(EntityUtils.toByteArray(entity));
} catch (IOException ie) {
throw new IOException("IO exception",ie);
} finally {
httpclient.getConnectionManager().shutdown();
}
return is;
堆栈跟踪示例:
Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:421)
at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:390)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:148)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:121)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:561)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
Tomcat JAVA_OPTS:
JAVA_OPTS="-server -Xms4g -Xmx4g -XX:PermSize=512m -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC -Dfile.encoding=UTF-8 -Djavax.net.ssl.trustStore=/usr/lib/jvm/java-7-oracle/jre/lib/security/cacerts -Djavax.net.ssl.trustStorePassword=changeit"
【问题讨论】:
-
您应该使用来自实际生产服务器的一些 CLI 工具检查您访问的任何 URL 的 SSL 证书,并检查此证书是否与您在本地获得的证书相匹配,例如使用您的浏览器。有关您的一些选择,请参阅this question。也许有一些代理可以终止远程 SSL?!
-
@dpr 谢谢,遗憾的是他们匹配。我正在连接知名服务,例如 imgur 或 mailgun。
标签: java ssl httpclient