【发布时间】: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