gpt4 book ai didi

java - MTLS 和 http 客户端连接池使用情况

转载 作者:行者123 更新时间:2023-12-04 22:35:59 26 4
gpt4 key购买 nike

背景

  • 我需要为各种客户端连接到服务器。
  • 每个客户端连接都应使用唯一的 TLS 证书。
  • MTLS 在服务器上就位。
  • 我想使用连接池来改善延迟。

  • 使用以下 http 客户端
    <dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.12</version>
    </dependency>
    我的假设
    在连接池中管理连接时,在选择连接时,应在选择连接池中的相同连接之前考虑客户端证书。
    我不希望使用 clientB TLS 证书与 clientA 建立连接,反之亦然。
    问题
    这个假设是真的吗?
    场景一)
    我将每条路线的最大连接数设置为 2。
    我为客户端 A 调用 MTLS 安全服务器。(池中的一个连接)
    我为客户端 A 调用 MTLS 安全服务器。(池中有两个连接)
    这不应该重用第一个连接吗?
    场景2)
    我将每条路线的最大连接数设置为 2。
    我为客户端 A 调用 MTLS 安全服务器。(池中的一个连接)
    我为客户端 B 调用 MTLS 安全服务器。(池中有两个连接)
    但是,第二次调用似乎没有进行完整的握手,而是使用了 clientA 证书。
    我希望第二次通话需要完整的握手,并且无论如何连接都不会相关。
    这是预期的行为吗?我在这里遗漏了一些明显的东西吗?
    更新了更简单的测试用例
    我们现在使用的是 http 上下文,所以我附上了更新的日志。
    我也简化了测试用例,现在它每次应该使用不同的客户端证书时连接到同一个服务器两次。
    该应用程序正在使用 spring boot,并且有一个 restTemplate 和一个 httpClient。
    它使用 PrivateKeyStrategy 来决定在与服务器通信时使用什么私钥/证书。
    第一个连接使用 key 别名“e2e_transport_key_id_franek”(您将在日志中看到这一点)
    第二个连接应该使用别名'e2e_transport_key_id_pdw'(在日志中从未见过)
    我们正在建立的第二个连接应该使用别名为“e2e_transport_key_id_pdw”的 key /证书,但是 session 已恢复,请参见第 448 行尝试恢复 session 。这意味着我们不能使用 PrivateKeyStrategy 来选择要使用的客户端证书。
    如何强制客户端连接不为我们打算使用不同客户端证书的连接重用 session ?
    客户端日志
    https://pastebin.com/zN0EW3Qy

    最佳答案

    Is this assumption true?


    你的假设是对的。 requesting的连接池方法和 releasing一个连接同时接受一个名为 state 的附加参数。此状态参数通常采用用户 token 或 null如果没有身份验证。
    仅当使用用于将连接释放回连接池的相同用户 token 请求连接时,才能重新使用连接。
    此机制也适用于 SSL 客户端证书。在 SSL 握手成功后,SSL 连接与 X500Principal 一起被释放。代表用户 token 。此 token 也存储在 HttpContext用于请求的对象。要在后续 HTTP 请求中重新使用已释放的连接,您还必须重新使用 HttpContext第一个 HTTP 请求。

    Scenario 1

    clientA.execute(new HttpGet("..."));
    clientA.execute(new HttpGet("..."));
    第一个请求触发完整的 SSL 握手。使用用户 token 释放连接。第二个请求使用新的 HttpContext其中不包含任何用户 token 。因此,池中的连接不能被重新使用,并且通过完全握手创建一个新连接。

    Scenario 2

    HttpContext context = new HttpClientContext();
    clientA.execute(new HttpGet("..."), context);
    clientB.execute(new HttpGet("..."), context);
    如前所述,用户 token 存储在 HttpContext 中。 .因此,如果您重新使用 HttpContext从第一个请求开始,即使您使用具有不同连接工厂/客户端证书的不同客户端,第二个请求也可以重新使用已经存在的连接。如果连接应该在使用中,将使用 clientB 的连接工厂创建一个新连接。
    分开 clientAclientB并且为了确保每个客户端只重复使用连接,您必须使用一个 HttpContext每个客户端并为每个请求重新使用上下文:
    HttpContext contextA = new HttpClientContext();
    clientA.execute(new HttpGet("..."), contextA);
    clientA.execute(new HttpGet("..."), contextA);

    HttpContext contextB = new HttpClientContext();
    clientB.execute(new HttpGet("..."), contextB);
    请注意,在 session 超时或请求重新协商的情况下,即使连接被重用,也可能需要完全握手。

    关于java - MTLS 和 http 客户端连接池使用情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63829066/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com