Доверять SSL-сертификатам: как HTTP-клиент Commons доверяет больше, чем стандарт Java? - PullRequest
2 голосов
/ 08 июля 2020

Чтобы проверить JWT, я использую jose4j для получения сертификата по URL-адресу, в данном случае из 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

Однако это вызывает ошибку сертификата:

Не удалось построить путь PKIX: sun.security.provider.certpath.SunCertPathBuilderException: невозможно найти действительный путь сертификации для запрошенной цели

Хорошо, да, я мог бы добавить его в трубу JVM с некоторыми скрипт, но я не хочу (так как в основном это не самозаверяющий сертификат, и он отлично работает в обычном браузере). В большинстве случаев я использую Apache HTTP-клиент 4.x, и по какой-то причине там вызов работает без проблем:

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

Я также пробовал использовать vanilla java, например new URL(jwksEndpointUrl).openStream(), и здесь у меня та же проблема с сертификатом.

Итак, что делает клиент Apache HttpComponents по-другому и как я могу добиться того же для стандартного Java HTTP GET через jose4j?

1 Ответ

5 голосов
/ 09 июля 2020

Поведение Liberty до недавнего времени заключалось в том, чтобы не доверять чему-либо по умолчанию, поэтому даже хорошо известные сертификаты, такие как сертификат от Google, должны быть добавлены в его хранилище доверенных сертификатов, чтобы избежать наблюдаемой ошибки.

В более поздних версиях , (190012+?) Можно установить "trustDefaultCerts = true", тогда он будет вести себя больше как браузер и по умолчанию доверяет сертификатам известных эмитентов, таких как Google. Вот пример фрагмента с сервера. xml:

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

...