且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java 11 HttpClient未发送基本身份验证

更新时间:2022-06-24 14:56:36

我正在调用的服务(在本例中为Atlassian的Jira Cloud API)支持基本身份验证和OAuth身份验证.我试图使用HTTP Basic,但它会发回OAuth的身份验证质询.

The service I was calling (in this case, Atlassian's Jira Cloud API) supports both Basic and OAuth authentication. I was attempting to use HTTP Basic, but it sends back an auth challenge for OAuth.

从当前的JDK 11开始,HttpClient不会发送基本凭据,直到使用来自服务器的WWW-Authenticate标头对其进行质询为止.此外,它了解的唯一挑战类型是基本身份验证.

As of the current JDK 11, HttpClient does not send Basic credentials until challenged for them with a WWW-Authenticate header from the server. Further, the only type of challenge it understands is for Basic authentication. The relevant JDK code is here (complete with TODO for supporting more than Basic auth) if you'd like to take a look.

与此同时,我的补救措施是绕过HttpClient的身份验证API,并自己创建和发送基本授权标头:

In the meantime, my remedy has been to bypass HttpClient's authentication API and to create and send the Basic Authorization header myself:

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());
}