Я использую клиентскую библиотеку HTTP JDK11, в которой я пытаюсь создать аутентификацию с определенной областью действия, которая может быть связана с хостом, портом, областью или схемой (BASIC, DIGEST и т. Д.).
Моя реализация класса:
class CredentialsProviderAuthenticator extends Authenticator {
private final AuthScope authScope;
private final Credentials credentials;
private CredentialsProviderAuthenticator(AuthScope authScope, Credentials credentials) {
this.authScope = authScope;
this.credentials = credentials;
}
public static Authenticator createAuthenticator(AuthScope authScope, Credentials credentials) {
return new CredentialsProviderAuthenticator(authScope, credentials);
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
if ( (authScope.getScheme() == null || authScope.getScheme().equalsIgnoreCase(getRequestingScheme()))
&& ((authScope.getHost() == null || authScope.getHost().equalsIgnoreCase(getRequestingHost())))
&& ((authScope.getRealm() == null || authScope.getRealm().equalsIgnoreCase(getRequestingPrompt())))
&& ((authScope.getPort() < 0) || authScope.getPort() == getRequestingPort())) {
return new PasswordAuthentication(credentials.getUserPrincipal().getName(), credentials.getPassword().toCharArray());
}
return null;
}
}
Эта реализация работает нормально, когда возвращается экземпляр PasswordAuthentication
, но клиент выдает исключение, когда подходящая аутентификация не найдена.
Caused by: java.io.IOException: No credentials provided
at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:565)
at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:119)
at com.imperva.shcf4j.java.http.client.ClosableSyncHttpClient.execute(ClosableSyncHttpClient.java:50)
... 27 more
Caused by: java.io.IOException: No credentials provided
at java.net.http/jdk.internal.net.http.AuthenticationFilter.response(AuthenticationFilter.java:303)
at java.net.http/jdk.internal.net.http.MultiExchange.responseFilters(MultiExchange.java:181)
at java.net.http/jdk.internal.net.http.MultiExchange.lambda$responseAsyncImpl$5(MultiExchange.java:245)
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1072)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture.postFire(CompletableFuture.java:610)
at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:649)
at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:478)
at java.net.http/jdk.internal.net.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:153)
at java.base/java.util.concurrent.CompletableFuture$UniCompletion.claim(CompletableFuture.java:568)
at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:638)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
at java.net.http/jdk.internal.net.http.Http1Response$HeadersReader.handle(Http1Response.java:677)
at java.net.http/jdk.internal.net.http.Http1Response$HeadersReader.handle(Http1Response.java:603)
at java.net.http/jdk.internal.net.http.Http1Response$Receiver.accept(Http1Response.java:594)
at java.net.http/jdk.internal.net.http.Http1Response$HeadersReader.tryAsyncReceive(Http1Response.java:650)
at java.net.http/jdk.internal.net.http.Http1AsyncReceiver.flush(Http1AsyncReceiver.java:228)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147)
at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Я ищу способ, которым в таких случаях клиент вернет код ошибки 401 HTTP. Одна идея состоит в том, чтобы создать экземпляр, который генерирует имя пользователя и пароль при каждом вызове, но, возможно, существует более простой подход?