Java 11 HttpClient не отправляет базовую аутентификацию - PullRequest
0 голосов
/ 16 января 2019

Я написал следующий код 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 Ответ

0 голосов
/ 16 января 2019

Служба, которую я вызывал (в данном случае Jira Cloud API от Atlassian), поддерживает как базовую, так и OAuth-аутентификацию. Я пытался использовать HTTP Basic, но он отправляет вызов аутентификации для OAuth.

Начиная с текущего JDK 11, HttpClient не отправляет базовые учетные данные, пока их не вызовут с заголовком WWW-Authenticate с сервера. Кроме того, единственный тип вызова, который он понимает, - это обычная проверка подлинности. Соответствующий код JDK находится здесь (в комплекте с TODO для поддержки не только базовой аутентификации), если вы хотите взглянуть.

Тем временем я решил обойти API аутентификации HttpClient, а также сам создать и отправить заголовок Basic Authorization:

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