Ignore self-signed ssl certificate with Jersey Client

I am using the jersey client library to run tests against a jboss-based leisure service. I have https configured on the server (running on localhost) using my own certificate.

However, whenever I run my tests using the https url, I get the following error:

com.sun.jersey.api.client.ClientHandlerException: 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 at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:131) at com.sun.jersey.api.client.Client.handle(Client.java:629) at com.sun.jersey.oauth.client.OAuthClientFilter.handle(OAuthClientFilter.java:137) at com.sun.jersey.api.client.WebResource.handle(WebResource.java:601) at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74) at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:459) at test.helper.Helper.sendSignedRequest(Helper.java:174) ... And so on 

I know this is due to the fact that my own certificate is not in the java repository. Is there any way to make Client not to verify the ssl certificate is correct and use it independently?

This code will only run on test servers, so I donโ€™t want to go about adding new trusted certificates every time we set up a new test server.

Here's the code calling the call:

 OAuthParameters params = new OAuthParameters(); // baseline OAuth parameters for access to resource params.signatureMethod(props.getProperty("signature_method")); params.consumerKey(props.getProperty("consumer_key")); params.setToken(props.getProperty("token")); params.setVersion("1.0"); params.nonce(); // OAuth secrets to access resource OAuthSecrets secrets = new OAuthSecrets(); secrets.consumerSecret(props.getProperty("consumer_secret")); secrets.setTokenSecret(props.getProperty("token_secret")); // Jersey client to make REST calls to token services Client client = Client.create(); // OAuth test server resource WebResource resource = client.resource(props.getProperty("url")); // if parameters and secrets remain static, filter cab be added to each web resource OAuthClientFilter filter = new OAuthClientFilter(client.getProviders(), params, secrets); // filter added at the web resource level resource.addFilter(filter); WebResource.Builder wbr = resource.getRequestBuilder().accept(props.getProperty("accept")); return wbr.get(ClientResponse.class); 

Any help would be greatly appreciated.

+60
java ssl jersey ssl-certificate
May 18 '11 at 16:32
source share
13 answers

After some searching and tipping over some old stackoverflow questions, I found a solution in a previously asked SO question:

Here is the code I used.

 // Create a trust manager that does not validate certificate chains TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager(){ public X509Certificate[] getAcceptedIssuers(){return null;} public void checkClientTrusted(X509Certificate[] certs, String authType){} public void checkServerTrusted(X509Certificate[] certs, String authType){} }}; // Install the all-trusting trust manager try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { ; } 
+83
May 19 '11 at 8:35
source share

For Jersey 2. * (tested at 2.7) and Java 8:

 import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; public static Client ignoreSSLClient() throws Exception { SSLContext sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(null, new TrustManager[]{new X509TrustManager() { public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}, new java.security.SecureRandom()); return ClientBuilder.newBuilder() .sslContext(sslcontext) .hostnameVerifier((s1, s2) -> true) .build(); } 
+51
Mar 16 '15 at 13:38
source share

I had the same problem and didnโ€™t want it to be configured globally, so I used the same TrustManager and SSLContext code as above, I just changed the client to be created with special properties

  ClientConfig config = new DefaultClientConfig(); config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties( new HostnameVerifier() { @Override public boolean verify( String s, SSLSession sslSession ) { // whatever your matching policy states } } )); Client client = Client.create(config); 
+10
Jun 15 '11 at 13:50
source share

This code will only run on test servers, so I donโ€™t want to move on to the difficulty of adding new trusted certificates every time we set up a new test server.

This is the code that will ultimately find its way into production (if not from you, someone who reads this question will copy and paste the unprotected trust managers that were proposed in their applications). It is just so easy to forget to delete this type of code when you have a deadline because it does not appear as a problem.

If you are worried about adding new certificates every time you have a test server, create your own CA, issue all the certificates for the test servers using this CA, and import this CA certificate into the client trust store. (Even if you are not dealing with things like revoking an online certificate in a local environment, this is certainly better than using a trust manager that passes something through.)

There are tools to help you do this, such as TinyCA or XCA .

+8
Aug 14 '13 at 13:18
source share

Since I am new to stackoverflow and have a lesser reputation for commenting on the answers of others, I put the solution proposed by Chris Sly, with some modification that worked for me.

  SSLContext ctx = null; TrustManager[] trustAllCerts = new X509TrustManager[]{new X509TrustManager(){ public X509Certificate[] getAcceptedIssuers(){return null;} public void checkClientTrusted(X509Certificate[] certs, String authType){} public void checkServerTrusted(X509Certificate[] certs, String authType){} }}; try { ctx = SSLContext.getInstance("SSL"); ctx.init(null, trustAllCerts, null); } catch (NoSuchAlgorithmException | KeyManagementException e) { LOGGER.info("Error loading ssl context {}", e.getMessage()); } SSLContext.setDefault(ctx); 
+8
Dec 10 '14 at 10:36
source share

For those on Jersey 2.x without lambdas, use this:

 import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; public static Client getUnsecureClient() throws Exception { SSLContext sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(null, new TrustManager[]{new X509TrustManager() { public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{} public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException{} public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } }}, new java.security.SecureRandom()); HostnameVerifier allowAll = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; return ClientBuilder.newBuilder().sslContext(sslcontext).hostnameVerifier(allowAll).build(); } 

Tested jersey-client 2.11 on JRE 1.7 .

+4
Jan 27 '17 at 17:58
source share

Just add the same code with the import. Also contains outstanding code required for compilation. At first, I was not able to figure out what was imported for this code. Also add the correct package for the X509Certificate. Got this job with trial and error:

 import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import javax.security.cert.CertificateException; import javax.security.cert.X509Certificate; import javax.ws.rs.core.MultivaluedMap; TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { java.security.cert.X509Certificate[] chck = null; ; return chck; } public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { // TODO Auto-generated method stub } public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { } public void checkClientTrusted( java.security.cert.X509Certificate[] arg0, String arg1) throws java.security.cert.CertificateException { // TODO Auto-generated method stub } public void checkServerTrusted( java.security.cert.X509Certificate[] arg0, String arg1) throws java.security.cert.CertificateException { // TODO Auto-generated method stub } } }; // Install the all-trusting trust manager try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection .setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { ; } 
+3
Dec 30 '15 at 15:40
source share

For Jersey 2. *:

 Client client = ClientBuilder.newBuilder() .hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }).build(); 

-> https://jersey.java.net/documentation/latest/migration.html

+1
Sep 10 '14 at 14:11
source share

For Jersey 1.X

  TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {} public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException {} public java.security.cert.X509Certificate[] getAcceptedIssuers() { // or you can return null too return new java.security.cert.X509Certificate[0]; } }}; SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { public boolean verify(String string, SSLSession sslSession) { return true; } }); 
0
Dec 29 '16 at 8:33
source share

Use lambda for Jersey 2.x

  ClientBuilder.newBuilder() .hostnameVerifier((HostnameVerifier) (h, s) -> { return true; }).build(); 
0
Dec 29 '16 at 9:25
source share

I noticed that when using the Apache http client configuration with the pool manager, the accepted answer does not work.

In this case, it seems that ClientConfig.sslContext and ClientConfig.hostnameVerifier ignored. Therefore, if you use the connection pool with the Apache HTTP client configuration, you can use the following code to ignore the ssl check:

  ClientConfig clientConfig = new ClientConfig(); // ... configure your clientConfig SSLContext sslContext = null; try { sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, new TrustManager[] { new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) { } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[] {}; } } }, null); } catch (NoSuchAlgorithmException e) { //logger.debug("Ignoring 'NoSuchAlgorithmException' while ignoring ssl certificate validation."); } catch (KeyManagementException e) { //logger.debug("Ignoring 'KeyManagementException' while ignoring ssl certificate validation."); } Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", new SSLConnectionSocketFactory(sslContext, new AbstractVerifier() { @Override public void verify(String host, String[] cns, String[] subjectAlts) { } })) .build(); connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager); return ClientBuilder.newClient(clientConfig); 
0
Sep 27 '18 at 16:43
source share

Well, Iโ€™d just want to add my class just because in the future some kind of developer may appear who wants to connect to the Netbackup server (or something like that) and do something from Java, ignoring the SSL certificate. This worked for me, and we use Windows Active Directory to authenticate with the Netbackup server.

 public static void main(String[] args) throws Exception { SSLContext sslcontext = null; try { sslcontext = SSLContext.getInstance("TLS"); } catch (NoSuchAlgorithmException ex) { Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex); } try { sslcontext.init(null, new TrustManager[]{new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; } @Override public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @Override public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { //throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } }}, new java.security.SecureRandom()); } catch (KeyManagementException ex) { Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex); } //HttpAuthenticationFeature feature = HttpAuthenticationFeature.basicBuilder().credentials(username, password).build(); ClientConfig clientConfig = new ClientConfig(); //clientConfig.register(feature); Client client = ClientBuilder.newBuilder().withConfig(clientConfig) .sslContext(sslcontext) .hostnameVerifier((s1, s2) -> true) .build(); //String the_url = "https://the_server:1556/netbackup/security/cacert"; String the_token; { String the_url = "https://the_server:1556/netbackup/login"; WebTarget webTarget = client.target(the_url); Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON); String jsonString = new JSONObject() .put("domainType", "NT") .put("domainName", "XX") .put("userName", "the username") .put("password", "the password").toString(); System.out.println(jsonString); Response response = invocationBuilder.post(Entity.json(jsonString)); String data = response.readEntity(String.class); JSONObject jo = new JSONObject(data); the_token = jo.getString("token"); System.out.println("token is:" + the_token); } { String the_url = "https://the_server:1556/netbackup/admin/jobs/1122012"; //job id 1122012 is an example WebTarget webTarget = client.target(the_url); Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON).header(HttpHeaders.AUTHORIZATION, the_token).header(HttpHeaders.ACCEPT, "application/vnd.netbackup+json;version=1.0"); Response response = invocationBuilder.get(); System.out.println("response status:" + response.getStatus()); String data = response.readEntity(String.class); //JSONObject jo = new JSONObject(data); System.out.println(data); } } 

I know that this can be considered off-topic, but I'm sure that a developer who is trying to connect to the Netbackup server is likely to be here. By the way, many thanks to all the answers to this question! The specification I'm talking about is here, and there is no Java example in their code examples (currently).

*** This, of course, is not safe, because we ignore the certificate!

0
Apr 03 '19 at 7:16
source share

worked for me with this code. Maybe for Java 1.7

  TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { // TODO Auto-generated method stub return null; } @Override public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { // TODO Auto-generated method stub } @Override public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { // TODO Auto-generated method stub } }}; // Install the all-trusting trust manager try { SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { ; } 
-3
Aug 14 '13 at 12:13
source share



All Articles