Open Liberty SSLHandshakeException для официального образа Docker microProfile3java11

Я пытаюсь получить доступ к фиктивному REST API, например https://reqres.in/api/users. или https://jsonplaceholder.typicode.com/todos с помощью простого клиента JAX-RS, например:

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);
    }
}

но каждый раз, когда я пытаюсь использовать HTTPS, я получаю сообщение SSLHandshakeExeption о том, что сервер: не удалось найти действительный путь сертификации к запрошенной цели:

[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

Dockerfile выглядит следующим образом:

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

Я предполагаю, что этот официальный образ Docker использует доверенные сертификаты JDK, или мне нужно явно настроить это в собственном server.xml?


person rieckpil    schedule 08.08.2019    source источник
comment
Liberty по умолчанию не использует доверенные сертификаты JDK. Если вы хотите использовать файл cacerts для доверия, его необходимо настроить. Я предполагаю, что у вас нет конфигурации ssl. Чтобы добавить файл cacerts, вы можете добавить следующую конфигурацию: ‹ssl id=defaultSSLConfig keyStoreRef=defaultKeyStore trustStoreRef=caTrustStore /› ‹keyStore id=caTrustStore location=“введите путь к типу файла cacerts=JKS password=changeit /›   -  person Alaine    schedule 08.08.2019
comment
спасибо, это устранило проблему. Вы хотите добавить формальный ответ, чтобы я мог отметить его как правильный? Потребовалось <ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="caTrustStore" /> <keyStore id="caTrustStore" location="${java.home}/lib/security/cacerts" password="changeit" />   -  person rieckpil    schedule 08.08.2019


Ответы (2)


Это на самом деле стало еще проще настроить с момента последнего поста. В элементе ssl есть атрибут, который указывает контексту SSL использовать хранилище доверенных сертификатов JVM по умолчанию в дополнение к настроенному.

<ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustDefaultCerts="true" />  
person Alaine    schedule 02.06.2021
comment
спасибо за обновление ответа упрощенным и актуальным примером - person rieckpil; 03.06.2021

Liberty по умолчанию не использует доверенные сертификаты JDK. Если вы хотите использовать файл cacerts для доверия, его необходимо настроить. Я предполагаю, что у вас нет конфигурации ssl. Чтобы добавить файл cacerts, вы можете добавить следующую конфигурацию:

 <ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="caTrustStore" />  
<keyStore id="caTrustStore" location=“enter path to cacerts file" type="JKS" password="changeit" />
person Alaine    schedule 12.08.2019
comment
Часами рвал на себе волосы. Спасибо! - person viragoboy; 28.05.2021