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.
SSLConnectionSocketFactory is a layered socket factory for TSL and SSL connections. Using this, you can verify the Https server using a list of trusted certificates and authenticate the given Https server. You can create this in many ways.
CloseableHttpClient is the base class of the httpclient library, the one all implementations use. Other subclasses are for the most part deprecated. The HttpClient is an interface for this class and other classes. You should then use the CloseableHttpClient in your code, and create it using the HttpClientBuilder .
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With