【问题标题】:How to do Preemptive authentication using Java 11 HTTP client?如何使用 Java 11 HTTP 客户端进行抢先式身份验证?
【发布时间】:2020-02-24 14:49:07
【问题描述】:

我正在尝试使用 Java 11 HTTP 客户端针对经过身份验证的服务,使用基本身份验证。 身份验证成功发生,但它与服务器进行了额外的往返,以了解它应该发送身份验证数据。

已经搜索过文档和代码,在某些时候它在内部使用了某种缓存,但我无法设置缓存值。

这是我的客户端代码:

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("http://someurl.com"))
        .build();

HttpClient client = HttpClient.newBuilder()
        .authenticator(new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("user", "pass".toCharArray());
            }
        })
        .build();

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

我所期望的是,我可以以某种方式告诉客户端抢先发送身份验证数据,而不仅仅是在服务器请求时。

【问题讨论】:

    标签: basic-authentication java-11 java-http-client


    【解决方案1】:

    HttpClient 的行为方式与HttpURLConnection 在抢占式身份验证方面的行为相同:对于基本身份验证,如果在缓存中找到凭据,它将抢先发送凭据。但是,缓存会在第一个成功请求之后填充(或者更准确地说,是在解析表明身份验证成功的响应标头之后)。

    如果这对您不满意,那么可以通过在您的请求中预先插入 Authorization 标头而不设置任何 Authenticator 来直接在您的代码中处理身份验证。

    【讨论】:

      【解决方案2】:

      感谢@daniel,这是我想出的解决方案,将标头添加到 HttpRequest 并删除 Authenticator。

      String encodedAuth = Base64.getEncoder()
              .encodeToString(("user" + ":" + "pass").getBytes(StandardCharsets.UTF_8));
      
      HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create("http://someurl.com"))
              .header("Authorization", "Basic " + encodedAuth)
              .build();
      
      HttpClient client = HttpClient.newHttpClient();
      
      HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
      
      

      希望客户端有其他方式来告诉抢先发送身份验证数据,而不是手动创建 Header,但是这样可以工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-12
        • 1970-01-01
        • 2014-08-29
        • 1970-01-01
        • 1970-01-01
        • 2021-04-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多