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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7684654/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 20:58:26  来源:igfitidea点击:

How to make Apache Commons HttpClient 3.1 ignore HTTPS certificate invalidity?

javahttpshttpclientapache-commons

提问by a CVn

I am trying to get the Apache Commons HttpClient library (version 3.1) to ignore the fact that the server certificate cannot be established as trusted (as evidenced by the thrown exception 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).

我试图让 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)。

I did find Make a connection to a HTTPS server from Java and ignore the validity of the security certificateas well as Disable Certificate Validation in Java SSL Connections, but the accepted answer to the first is for HttpClient 4.0 (unfortunately I cannot upgrade, unlesssomeone can point me in the direction of how to use two different versions of that same library within the same project), although it does have another answer with little more than a dead link that supposedly went to a 3.x solution. The code at the second page seems to have no effect at all when I use a slightly adjusted version of it (basically, declaring the classes in the old fashion rather than using anonymous ones inline, as well as applying to TLSin addition to SSL, using SSLfor the default HTTPS socket factory as done in the example code).

我确实发现Make a connection to a HTTPS server from Java 并忽略安全证书的有效性以及Disable Certificate Validation in Java SSL Connections,但第一个接受的答案是 HttpClient 4.0(不幸的是我无法升级,除非有人可以指向我如何在同一个项目中使用同一个库的两个不同版本的方向),尽管它确实有另一个答案,只不过是一个死链接,据说转到 3.x 解决方案。当我使用稍微调整过的版本时,第二页上的代码似乎完全没有效果(基本上,以旧方式声明类而不是使用内联匿名类,以及应用于TLS此外SSLSSL用于默认 HTTPS 套接字工厂,如示例代码中所做的那样)。

Preferably, I'd like something that is thread-/instance-wide, so that any HttpClientinstance (and/or related classes) being created from within my servlet code(notanother servlet running in the same container) will use the lax certificate validation logic, but at this point I am starting to feel like anything will do as long as it accepts the self-signed certificate as valid.

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

Yes, I am aware that there are security implications, but the only reason why I need this at all is for testing purposes. The idea is to implement a configuration option that controls whether normally untrusted certificates are trusted or not, and leave it in "don't trust non-trustworthy server certificates" as default. That way it can easily be turned on or off in development, but doing it in production will require going out of one's way.

是的,我知道存在安全隐患,但我需要它的唯一原因是为了测试目的。这个想法是实现一个配置选项来控制通常不受信任的证书是否受信任,并将其保留在“不信任不可信的服务器证书”中作为默认值。这样就可以很容易地在开发中打开或关闭它,但在生产中这样做需要特意避开。

回答by Gandalf

To accept selfsigned certificates we use the following code for a particular HttpConnectionfrom commons http client.

为了接受自签名证书,我们将以下代码用于HttpConnection来自 commons http 客户端的特定代码。

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

The EasySSLProtocolSocketFactorycan be found in the contrib ssl package. And this can be used to make only single connections with the reduced security setting. It seems like this can also be used to set the protocol for every client as shown here:

EasySSLProtocolSocketFactory可以在contrib SSL包中找到。这可用于仅建立具有降低安全设置的单一连接。似乎这也可用于为每个客户端设置协议,如下所示:

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);

But I think that will also influence connections from other servlets.

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

[Edit] Sorry, I don't know if this will work for you. Just recognized that we are using client 3.0.1 and not 3.1.

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