代码之家  ›  专栏  ›  技术社区  ›  Jonathan Fuerth

Java 11 HTTP客户端不发送基本身份验证

  •  5
  • Jonathan Fuerth  · 技术社区  · 7 年前

    我编写了以下httpclient代码,但它没有导致 Authorization 正在发送到服务器的头:

    public static void main(String[] args) {
        var client = HttpClient.newBuilder()
                .authenticator(new Authenticator() {
                    @Override
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication("username", "password".toCharArray());
                    }
                })
                .version(HttpClient.Version.HTTP_1_1)
                .build();
        var request = HttpRequest.newBuilder()
                .uri("https://service-that-needs-auth.example/")
                .build();
        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(HttpResponse::body)
                .thenAccept(System.out::println)
                .join();
    }
    

    我正在调用的服务中收到HTTP 401错误。在我的例子中,它是Atlassian Jira Cloud API。

    我已经确认 getPasswordAuthentication() httpclient未调用方法。

    为什么它不起作用,我应该怎么做?

    1 回复  |  直到 7 年前
        1
  •  8
  •   Eugene    7 年前

    我调用的服务(在本例中是Atlassian的JiraCloudAPI)支持基本身份验证和OAuth身份验证。我试图使用HTTPBasic,但它向OAuth发送了一个身份验证质询。

    从当前的JDK 11开始,httpclient不会发送基本凭证,直到服务器发出带有www-authenticate头的询问。此外,它理解的唯一挑战类型是基本身份验证。 The relevant JDK code is here (完成todo以支持基本身份验证)如果您想看一下。

    同时,我的补救方法是绕过httpclient的身份验证API,自己创建和发送基本的授权头:

    public static void main(String[] args) {
        var client = HttpClient.newBuilder()
                .version(HttpClient.Version.HTTP_1_1)
                .build();
        var request = HttpRequest.newBuilder()
                .uri(new URI("https://service-that-needs-auth.example/"))
                .header("Authorization", basicAuth("username", "password"))
                .build();
        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(HttpResponse::body)
                .thenAccept(System.out::println)
                .join();
    }
    
    private static String basicAuth(String username, String password) {
        return "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes());
    }
    
    推荐文章