1

I'm trying to access a dummy REST API like https://reqres.in/api/users or https://jsonplaceholder.typicode.com/todos with a simple JAX-RS client like:

public class RandomDataProvider {

    private WebTarget webTarget;

    @PostConstruct
    public void setUp() {
        Client client = ClientBuilder.newBuilder()
                .connectTimeout(5, TimeUnit.SECONDS)
                .readTimeout(5, TimeUnit.SECONDS)
                .build();

        this.webTarget = client
                .target("https://reqres.in/api/users");
    }


    public JsonArray getAllPosts() {
        return this.webTarget
                .request()
                .accept(MediaType.APPLICATION_JSON)
                .get(JsonArray.class);
    }
}

but everytime I try to use HTTPS I get the SSLHandshakeExeption that the server was: unable to find valid certification path to requested target:

[ERROR   ] SRVE0283E: Exception caught while initializing context: javax.ws.rs.ProcessingException: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://reqres.in/api/users: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at org.apache.cxf.jaxrs.client.AbstractClient.checkClientException(AbstractClient.java:640)
        at [internal classes]
        at de.rieckpil.udemy.RandomDataProvider.getAllPosts(RandomDataProvider.java:32)
        at de.rieckpil.udemy.RandomDataPrinter.initialize(RandomDataPrinter.java:17)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:95)
        at [internal classes]
Caused by (repeated) ... : javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://reqres.in/api/users: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
        at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
        at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1451)
        ... 9 more
Caused by: java.security.cert.CertificateException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
        at com.ibm.ws.ssl.core.WSX509TrustManager.checkServerTrusted(WSX509TrustManager.java:806)
        ... 9 more

The Dockerfile looks like the following:

FROM open-liberty:microProfile3-java11
COPY --chown=1001:0  target/mywar.war /config/dropins/

I'm assuming that this official Docker image is using the JDK trusted certificates or do I have to configure this explicitly in an own server.xml?

rieckpil
  • 10,470
  • 3
  • 32
  • 56
  • Liberty does not use the JDK's trusted certificates by default. If you want to use the cacerts file for trust then it will have to be configured. I'll assume you have no ssl configuration. To add the cacerts file you can add a configuration like this: – Alaine Aug 08 '19 at 15:53
  • thanks, that fixed the issue. Do you want to add a formal answer so I can mark it as the right one? It took ` ` – rieckpil Aug 08 '19 at 19:23

2 Answers2

2

Liberty does not use the JDK's trusted certificates by default. If you want to use the cacerts file for trust then it will have to be configured. I'll assume you have no ssl configuration. To add the cacerts file you can add a configuration like this:

 <ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="caTrustStore" />  
<keyStore id="caTrustStore" location=“enter path to cacerts file" type="JKS" password="changeit" />
Alaine
  • 419
  • 2
  • 5
2

This has actually gotten even easier to configure since that last post. There is an attribute on the ssl element that will tell the SSL context to use the JVM's default truststore in addition to the configure one.

<ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustDefaultCerts="true" />  
Alaine
  • 419
  • 2
  • 5