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

19,806

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.

Share:
19,806

Related videos on Youtube

user
Author by

user

Updated on June 04, 2022

Comments

  • user
    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 to SSL, using SSL 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
    user over 12 years
    Yes, 3.1 has deprecated the Protocol constructor you exemplify, and has no HttpConnection#setProtocol method at all apparently. Pity, it did look promising. :(
  • Gandalf
    Gandalf over 12 years
    The Constructor is also deprecated in 3.0.1 ;) According to the apache source repository HttpConnection still has a setProtocol method in 3.1: svn.apache.org/viewvc/httpcomponents/oac.hc3x/tags/…
  • Gandalf
    Gandalf over 12 years
    The 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
    user over 12 years
    oops, 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
    Gandalf over 12 years
    Such things happen to all of us I fear ;) When tweaking the HttpClient one could go the way of providing it a wrapped version of HttpConnectionManager I think.
  • user
    user over 12 years
    The 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
    Gandalf over 12 years
    Sorry 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
    Domchi over 10 years
    This is the only thing that worked for me for ancient 3.0.1 version of HTTPClient and Java 1.5. Eternally grateful.
  • Mehdi
    Mehdi over 6 years
    I use https-commons 3.1.x . The second example gave me an exception : ava.lang.AbstractMethodError: org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSoc‌​ketFactory.createSoc‌​ket(Ljava/lang/Strin‌​g;ILjava/net/InetAdd‌​ress;ILorg/apache/co‌​mmons/httpclient/par‌​ams/HttpConnectionPa‌​rams;)Ljava/net/Sock‌​et;