How to make Apache Commons HttpClient 3.1 ignore HTTPS certificate invalidity?
To accept selfsigned certificates we use the following code for a particular HttpConnection
from commons http client.
HttpConnection con = new HttpConnection(host, port);
con.setProtocol(new Protocol("easyhttps", (ProtocolSocketFactory)new EasySSLProtocolSocketFactory(), port));
The EasySSLProtocolSocketFactory
can 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:
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.
[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.
Related videos on Youtube
user
Updated on June 04, 2022Comments
-
user almost 2 years
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
).I did find Make a connection to a HTTPS server from Java and ignore the validity of the security certificate as 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, unless someone 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
TLS
in addition toSSL
, usingSSL
for the default HTTPS socket factory as done in the example code).Preferably, I'd like something that is thread-/instance-wide, so that any
HttpClient
instance (and/or related classes) being created from within my servlet code (not another 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.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.
-
user over 12 yearsYes, 3.1 has deprecated the Protocol constructor you exemplify, and has no HttpConnection#setProtocol method at all apparently. Pity, it did look promising. :(
-
Gandalf over 12 yearsThe Constructor is also deprecated in 3.0.1 ;) According to the apache source repository
HttpConnection
still has asetProtocol
method in 3.1: svn.apache.org/viewvc/httpcomponents/oac.hc3x/tags/… -
Gandalf over 12 yearsThe factory can be cast to
ProtocolSocketFactory
, which is only an upcast and hence not necessary if they remove the deprecated constructor, then it uses the non-deprecated contructor already now, I'll update my post. -
user over 12 yearsoops, I don't know what made me do it but I thought HttpConnection#setProtocol when in fact I was looking at HttpClient#setProtocol. And in my case I can't even blame it on not enough coffee. Going to have another stab at seeing if I can make this work in the framework of the code I have...
-
Gandalf over 12 yearsSuch things happen to all of us I fear ;) When tweaking the
HttpClient
one could go the way of providing it a wrapped version ofHttpConnectionManager
I think. -
user over 12 yearsThe second example in your answer "works" in the sense that it doesn't throw an exception, but with it, running against a host using a self-signed cert, I get a blank response back. Running against one that has a CA-signed cert, I get a normal response. I will of course do some more debugging, but any insights as to what might be going on?
-
Gandalf over 12 yearsSorry no, we have always used the first example (the second is from the java doc of
EasySSLProtocolSocketFactory
) and it always worked as expected so far. -
Domchi over 10 yearsThis is the only thing that worked for me for ancient 3.0.1 version of HTTPClient and Java 1.5. Eternally grateful.
-
Mehdi over 6 yearsI use https-commons 3.1.x . The second example gave me an exception : ava.lang.AbstractMethodError: org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory.createSocket(Ljava/lang/String;ILjava/net/InetAddress;ILorg/apache/commons/httpclient/params/HttpConnectionParams;)Ljava/net/Socket;