How to make Apache Commons HttpClient 3.1 ignore HTTPS certificate invalidity?
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 开发者_StackOverflow社区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.
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.
精彩评论