2

To validate a JWT, I'm using jose4j to get certificate from an url, in this case, from google:

    HttpsJwks httpsJkws = new HttpsJwks("https://www.googleapis.com/oauth2/v3/certs");
    HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws);
    //httpsJkws.setSimpleHttpGet(simpleHttpGet);
    JwtConsumer jwtConsumer = new JwtConsumerBuilder()
            .setVerificationKeyResolver(httpsJwksKeyResolver)
            .build(); // create the JwtConsumer instance

However, this gets me a certificate error:

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Ok yes, I could add it to the JVM's trustore with some script, but I don't want to (as basically, it's not a self-signed certificate, and work just fine via a regular browser). Most of the time, I use Apache HTTP client 4.x, and for some reason, there, the call does work without issues:

    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        HttpResponse httpResponse = httpClient.execute(new HttpGet("https://www.googleapis.com/oauth2/v3/certs"));
        String response = (httpResponse.getEntity() != null) ? EntityUtils.toString(httpResponse.getEntity()) : null;
        log.debug(response);
    } catch (IOException e) {
        log.error("I/O Error when retrieving content from '" + jwksEndpointUrl + "': " + e.getMessage());
    }

I also tried with vanilla java, like new URL(jwksEndpointUrl).openStream(), and here I get the same certificate issue.

So, what does Apache HttpComponents client do differently, and how can I achieve the same for a standard Java HTTP GET of via jose4j?

Steven De Groote
  • 2,187
  • 5
  • 32
  • 52
  • Please check if the certificate validation is disabled in Apache HttpComponents client. – Puce Jul 08 '20 at 20:10
  • As you can see, I'm creating a default client, and then doing a get. I haven't done any SSL customisation, so I assume it's validating. Is there something else to check? – Steven De Groote Jul 08 '20 at 21:33
  • Are you sure what jwksEndpointUrl is? With `new URL("https://www.googleapis.com/oauth2/v3/certs")` I get correct data (and no cert errror) on a dozen versions of Oracle Java (from 6 through 14) I have to hand. Note Google has its own intermediate CA (now) under GlobalSign Root R2, a long-established root. You could try running the jose4j case with system property `javax.net.debug=ssl,trustmanager` and it might show what's going wrong. – dave_thompson_085 Jul 09 '20 at 01:53
  • Yep, URL is fine – Steven De Groote Jul 09 '20 at 06:24
  • I have meanwhile found it this problem only happens when running on IBM liberty. The error suggests to add cert to /wlp-webProfile8-19.0.0.11/wlp/usr/servers/defaultServer/resources/security/key.p12 . But why? And why does apache httpclient work? – Steven De Groote Jul 09 '20 at 06:25

1 Answers1

5

Liberty's behavior until recently was to not trust anything by default, so even well known certificates like the one from Google have to be added to it's truststore to avoid the error you are seeing.

In more recent versions, (190012+ ?) one can set "trustDefaultCerts=true", then it behaves more like a browser and trusts certificates from well-known issuers like Google by default. Here's an example snippet from server.xml:

<keyStore id="defaultKeyStore" password="keyspass" /> <ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustDefaultCerts="true"/>

Bruce T.
  • 992
  • 4
  • 5