【问题标题】:Trusting SSL certificates: how does Commons HTTP client trust more than standard Java?信任 SSL 证书:Commons HTTP 客户端如何比标准 Java 更信任?
【发布时间】:2020-10-29 07:58:30
【问题描述】:

为了验证 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 的 trustore 中,但我不想这样做(基本上,它不是自签名证书,并且可以通过常规浏览器正常工作)。大多数时候,我使用 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 客户端有何不同之处,我如何通过 jose4j 实现标准 Java HTTP GET?

【问题讨论】:

  • 请检查 Apache HttpComponents 客户端是否禁用了证书验证。
  • 如您所见,我正在创建一个默认客户端,然后进行获取。我还没有进行任何 SSL 自定义,所以我认为它正在验证。还有什么要检查的吗?
  • 你确定 jwksEndpointUrl 是什么?使用new URL("https://www.googleapis.com/oauth2/v3/certs"),我可以在十几个版本的 Oracle Java(从 6 到 14)上获得正确的数据(并且没有证书错误)。注意 Google 在 GlobalSign Root R2 下拥有自己的中间 CA(现在),这是一个长期建立的根。您可以尝试使用系统属性 javax.net.debug=ssl,trustmanager 运行 jose4j 案例,它可能会显示出问题所在。
  • 是的,网址没问题
  • 我同时发现这个问题只有在 IBM liberty 上运行时才会发生。该错误建议将证书添加到 /wlp-webProfile8-19.0.0.11/wlp/usr/servers/defaultServer/resources/security/key.p12 。但为什么?以及为什么 apache httpclient 可以工作?

标签: java ssl apache-httpclient-4.x websphere-liberty jose4j


【解决方案1】:

直到最近,Liberty 的行为默认情况下不信任任何东西,因此即使是像 Google 一样的知名证书也必须添加到它的信任库中,以避免您看到的错误。

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

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

【讨论】:

    猜你喜欢
    • 2014-02-14
    • 1970-01-01
    • 2016-10-24
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 2012-11-03
    相关资源
    最近更新 更多