【问题标题】:Java HttpClient with TLS/SSLContext through proxy通过代理使用 TLS/SSLContext 的 Java HttpClient
【发布时间】:2020-11-25 09:35:32
【问题描述】:

我想对使用 TLS 进行身份验证的服务器进行 HTTP 调用。此外,服务器需要将我的 IP 列入白名单,因此对于 AWS Lambda,我需要使用代理。我想要实现的是通过代理的带有 TLS 的 HTTP POST 请求。

为了实现 TLS 协议,我使用带有加载证书和私钥的 KeyStore。 在没有代理的情况下拨打电话(从白名单 IP 本地)有效,所以我假设 keyStore 配置正确。

这是我如何构建httpClient(它是java.net.http.HttpClient):

var keyManagerFactory = KeyManagerFactory.getInstance("PKIX");
keyManagerFactory.init(keyStore, null);

var trustManagerFactory = TrustManagerFactory.getInstance("PKIX");
trustManagerFactory.init(keyStore, null);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

URI proxyUri = config.getProxyUri(); // this is injected object with preloaded config parameters

HttpClient httpClient = HttpClient.newBuilder()
    .sslContext(sslContext)
    .proxy(
      ProxySelector.of(
        InetSocketAddress.createUnresolved(proxyUri.getHost(), proxyUri.getPort())))
    .build();

现在提出请求:

String body = createRequestBody(); // creates string with JSON

HttpRequest request = HttpRequest.newBuilder()
    .uri(config.getServiceUri()) // same config as in example above
    .header("Content-Type", "application/json")
    .POST(BodyPublishers.ofString(body))
    .build();

HttpResponse<String> response = httpClient.send(request, BodyHandlers.ofString());

调用.send(...) 原因

java.io.IOException: Tunnel failed, got: 403
# java.net.http/jdk.internal.net.http.HttpClientImpl.send(Unknown Source)
# java.net.http/jdk.internal.net.http.HttpClientFacade.send(Unknown Source)
# (method we are in above example)

代理不需要任何身份验证,在其他 AWS Lambda 中,我已经看到此代理与构建器一起使用仅使用 .proxy(...) 方法,就像上面的示例一样。所以唯一不同的是这个.sslContext(...)

我需要更多sslContext 配置吗?我一直在寻找一些通过代理使用 TLS 的示例,但我没有找到任何东西。 HttpClient.Builder Docs 也没有提到任何关于使用 sslContext 的代理。

感谢您的帮助!

【问题讨论】:

  • 您似乎没有足够的权限访问您尝试使用的服务 (en.wikipedia.org/wiki/HTTP_403)。我建议使用 -Djdk.httpclient.HttpClient.log=errors,requests,headers 打开日志记录,看看是否有任何交换的标头可以为您提供有关可能出现问题的线索。

标签: java tls1.2 http-proxy java-http-client


【解决方案1】:

正如丹尼尔在评论中所写的那样

您似乎没有足够的权限访问您尝试使用的服务

原来是代理配置阻止了到该特定主机和端口的流量。 上面的代码没有任何问题。更改代理设置后,它按预期工作。

感谢您的帮助!

【讨论】:

    猜你喜欢
    • 2012-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-06
    • 2015-09-13
    • 2015-01-04
    • 1970-01-01
    • 2020-07-27
    相关资源
    最近更新 更多