信任 SSL 证书:Commons HTTP 客户端如何比标准 Java 信任更多?

Ste*_*ote 2 java ssl websphere-liberty apache-httpclient-4.x jose4j

为了验证 JWT,我使用 jose4j 从 url 获取证书,在这种情况下,从谷歌:

    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
Run Code Online (Sandbox Code Playgroud)

但是,这让我得到一个证书错误:

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());
    }
Run Code Online (Sandbox Code Playgroud)

我也尝试过使用 vanilla java,比如new URL(jwksEndpointUrl).openStream(),在这里我遇到了同样的证书问题。

那么,Apache HttpComponents 客户端有何不同,我如何通过 jose4j 实现标准 Java HTTP GET 的相同功能?

Bru*_* T. 5

直到最近,Liberty 的行为都是默认不信任任何东西,因此即使是众所周知的证书,例如来自 Google 的证书,也必须添加到它的信任库中,以避免出现您所看到的错误。

在较新的版本中,(190012+ ?)可以设置“trustDefaultCerts=true”,然后它的行为更像浏览器,并且默认情况下信任来自知名发行商(如 Google)的证书。这是 server.xml 中的示例片段:

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