如何使Apache Commons HttpClient 3.1忽略HTTPS证书无效?

时间:2011-10-07 08:18:24

标签: java https httpclient apache-commons

我试图让Apache Commons HttpClient库(版本3.1)忽略服务器证书无法建立为受信任的事实(由抛出的异常javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target证明)。

我确实找到Make a connection to a HTTPS server from Java and ignore the validity of the security certificate以及Disable Certificate Validation in Java SSL Connections,但第一个接受的答案是针对HttpClient 4.0(遗憾的是我无法升级,除非有人可以指向我如何在同一个项目中使用同一个库的两个不同版本的方向),尽管它确实有another answer with little more than a dead link that supposedly went to a 3.x solution。当我使用稍微调整的版本时,第二页上的代码似乎完全没有效果(基本上,以旧方式声明类而不是使用内联的匿名类,以及应用于TLS添加到SSL,使用SSL作为默认HTTPS套接字工厂,如示例代码中所示。)

最好,我想要一些线程/实例范围的东西,以便从我的servlet代码中创建的任何HttpClient实例(和/或相关类) not 在同一容器中运行的另一个servlet)将使用宽松的证书验证逻辑,但此时我开始觉得只要它接受自签名证书有效就会做任何事情。

是的,我知道存在安全隐患,但我完全需要这个的唯一原因是出于测试目的。我们的想法是实现一个配置选项来控制通常不受信任的证书是否可信,并将其保留为“不信任不可信赖的服务器证书”作为默认值。这样,它可以在开发过程中轻松打开或关闭,但在生产中执行它将需要不受欢迎。

1 个答案:

答案 0 :(得分:11)

要接受自签名证书,我们对commons http客户端的特定HttpConnection使用以下代码。

HttpConnection con = new HttpConnection(host, port);
con.setProtocol(new Protocol("easyhttps", (ProtocolSocketFactory)new EasySSLProtocolSocketFactory(), port));

可以在contrib ssl包中找到EasySSLProtocolSocketFactory。这可以用于仅使用降低的安全设置进行单个连接。 看起来这也可以用来为每个客户端设置协议,如下所示:

Protocol easyhttps = new Protocol("https", (ProtocolSocketFactory)new EasySSLProtocolSocketFactory(), 443);
Protocol.registerProtocol("https", easyhttps);

HttpClient client = new HttpClient();
GetMethod httpget = new GetMethod("https://localhost/");
client.executeMethod(httpget);

但我认为这也会影响来自其他servlet的连接。

[编辑] 对不起,我不知道这是否适合您。刚认识到我们使用的是客户端3.0.1而不是3.1。