【发布时间】:2020-12-28 21:57:24
【问题描述】:
背景
- 我需要为各种客户端连接到服务器。
- 每个客户端连接都应使用唯一的 TLS 证书。
- MTLS 在服务器上就位。
- 我想使用连接池来改善延迟。
使用如下http客户端
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.12</version>
</dependency>
我的假设 在连接池中管理连接时,在选择连接时,应在选择连接池中的相同连接之前考虑客户端证书。 我不希望使用 clientB TLS 证书与 clientA 建立连接,反之亦然。
问题 这个假设是真的吗?
场景 1)
我将每条路线的最大连接数设置为 2。 我为客户端 A 调用 MTLS 安全服务器。(池中的一个连接) 我为客户端 A 调用 MTLS 安全服务器。(池中有两个连接) 这不应该重用第一个连接吗?
场景 2)
我将每条路线的最大连接数设置为 2。 我为客户端 A 调用 MTLS 安全服务器。(池中的一个连接) 我为客户端 B 调用 MTLS 安全服务器。(池中有两个连接)
但是,第二次调用似乎没有执行完整的握手,而是使用了 clientA 证书。
我希望第二次通话需要完全握手,并且无论如何连接都不会相关。
这是预期的行为吗?我在这里遗漏了什么明显的东西吗?
更新了更简单的测试用例
我们现在使用的是 http 上下文,所以我附上了更新的日志。 我也简化了测试用例,现在它每次应该使用不同的客户端证书时连接到同一个服务器两次。
应用程序正在使用 spring boot,并且有一个 restTemplate 和一个 httpClient。
它使用 PrivateKeyStrategy 来决定在与服务器通信时使用什么私钥/证书。
第一个连接使用密钥别名“e2e_transport_key_id_franek”(您将在日志中看到这一点)
第二个连接应该使用别名'e2e_transport_key_id_pdw'(在日志中从未见过)
我们建立的第二个连接应该使用别名为“e2e_transport_key_id_pdw”的密钥/证书,但是会话已恢复,请参见第 448 行尝试恢复会话。这意味着我们不能使用 PrivateKeyStrategy 来选择要使用的客户端证书。
如何强制客户端连接不为我们打算使用不同客户端证书的连接重用会话?
【问题讨论】:
-
我可能不太明白您遇到的问题。我可以清楚地看到所有三个请求的新连接请求和完整的 TLS 握手。
-
我在问题中添加了额外的细节,谢谢
-
我清楚地看到了三个不同的连接和三个不同的 TLS 握手。很抱歉,我不明白您遇到的问题。是关于第三次消息交换没有重新使用第一次的连接吗?
-
PoolingHttpClientConnectionManager - Connection request: [route: {s}->https://server:8443][total available: 2; route allocated: 2 of 2; total allocated: 2 of 20]第三个请求不包含状态(用户令牌),所以HttpClient不重用现有的持久有状态连接是绝对正确的。 -
您设置 TLS 上下文的方式有问题。您很可能需要使用不同的 TLS 会话缓存来发出不同的请求,或者使用
SSLSession#invalidate()手动使 TLS 会话无效以防止它们恢复。
标签: java ssl tls1.2 apache-httpclient-4.x mtls