View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.hc.client5.testing.async;
28  
29  import static org.hamcrest.MatcherAssert.assertThat;
30  
31  import java.security.SecureRandom;
32  import java.util.Arrays;
33  import java.util.Collections;
34  import java.util.Queue;
35  import java.util.concurrent.ConcurrentLinkedQueue;
36  import java.util.concurrent.ExecutionException;
37  import java.util.concurrent.Future;
38  import java.util.concurrent.atomic.AtomicLong;
39  import java.util.function.Consumer;
40  import java.util.stream.Collectors;
41  
42  import org.apache.hc.client5.http.AuthenticationStrategy;
43  import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
44  import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
45  import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
46  import org.apache.hc.client5.http.auth.AuthCache;
47  import org.apache.hc.client5.http.auth.AuthSchemeFactory;
48  import org.apache.hc.client5.http.auth.AuthScope;
49  import org.apache.hc.client5.http.auth.BearerToken;
50  import org.apache.hc.client5.http.auth.CredentialsProvider;
51  import org.apache.hc.client5.http.auth.StandardAuthScheme;
52  import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
53  import org.apache.hc.client5.http.config.RequestConfig;
54  import org.apache.hc.client5.http.impl.DefaultAuthenticationStrategy;
55  import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
56  import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
57  import org.apache.hc.client5.http.impl.auth.BasicScheme;
58  import org.apache.hc.client5.http.impl.auth.CredentialsProviderBuilder;
59  import org.apache.hc.client5.http.protocol.HttpClientContext;
60  import org.apache.hc.client5.testing.BasicTestAuthenticator;
61  import org.apache.hc.client5.testing.auth.Authenticator;
62  import org.apache.hc.client5.testing.auth.BearerAuthenticationHandler;
63  import org.apache.hc.core5.function.Decorator;
64  import org.apache.hc.core5.http.ContentType;
65  import org.apache.hc.core5.http.HttpHeaders;
66  import org.apache.hc.core5.http.HttpHost;
67  import org.apache.hc.core5.http.HttpRequestInterceptor;
68  import org.apache.hc.core5.http.HttpResponse;
69  import org.apache.hc.core5.http.HttpResponseInterceptor;
70  import org.apache.hc.core5.http.HttpStatus;
71  import org.apache.hc.core5.http.ProtocolException;
72  import org.apache.hc.core5.http.URIScheme;
73  import org.apache.hc.core5.http.config.Lookup;
74  import org.apache.hc.core5.http.config.Registry;
75  import org.apache.hc.core5.http.config.RegistryBuilder;
76  import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
77  import org.apache.hc.core5.http.support.BasicResponseBuilder;
78  import org.apache.hc.core5.net.URIAuthority;
79  import org.apache.hc.core5.testing.nio.H2TestServer;
80  import org.hamcrest.CoreMatchers;
81  import org.junit.jupiter.api.Assertions;
82  import org.junit.jupiter.api.Test;
83  import org.mockito.Mockito;
84  
85  public abstract class AbstractHttpAsyncClientAuthenticationTest<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase {
86  
87      public AbstractHttpAsyncClientAuthenticationTest(final URIScheme scheme) {
88          super(scheme);
89      }
90  
91      abstract protected H2TestServer startServer(final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception;
92  
93      protected H2TestServer startServer() throws Exception {
94          return startServer(requestHandler -> new AuthenticatingAsyncDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")));
95      }
96  
97      interface TestClientBuilder {
98  
99          TestClientBuilder setDefaultAuthSchemeRegistry(Lookup<AuthSchemeFactory> authSchemeRegistry);
100 
101         TestClientBuilder setTargetAuthenticationStrategy(AuthenticationStrategy targetAuthStrategy);
102 
103         TestClientBuilder addResponseInterceptor(HttpResponseInterceptor responseInterceptor);
104 
105         TestClientBuilder addRequestInterceptor(HttpRequestInterceptor requestInterceptor);
106 
107     }
108 
109     abstract protected T startClientCustom(final Consumer<TestClientBuilder> clientCustomizer) throws Exception;
110 
111     T startClient() throws Exception {
112         return startClientCustom(c -> {});
113     }
114 
115     @Test
116     public void testBasicAuthenticationNoCreds() throws Exception {
117         final H2TestServer server = startServer();
118         server.register("*", AsyncEchoHandler::new);
119         final HttpHost target = targetHost();
120 
121         final T client = startClient();
122 
123         final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
124         final HttpClientContext context = HttpClientContext.create();
125         context.setCredentialsProvider(credsProvider);
126 
127         final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
128                         .setHttpHost(target)
129                         .setPath("/")
130                         .build(), context, null);
131         final HttpResponse response = future.get();
132 
133         Assertions.assertNotNull(response);
134         Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
135         Mockito.verify(credsProvider).getCredentials(
136                 Mockito.eq(new AuthScope(target, "test realm", "basic")), Mockito.any());
137     }
138 
139     @Test
140     public void testBasicAuthenticationFailure() throws Exception {
141         final H2TestServer server = startServer();
142         server.register("*", AsyncEchoHandler::new);
143         final HttpHost target = targetHost();
144 
145         final T client = startClient();
146 
147         final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
148         Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
149                 .thenReturn(new UsernamePasswordCredentials("test", "all-wrong".toCharArray()));
150         final HttpClientContext context = HttpClientContext.create();
151         context.setCredentialsProvider(credsProvider);
152 
153         final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
154                         .setHttpHost(target)
155                         .setPath("/")
156                         .build(), context, null);
157         final HttpResponse response = future.get();
158 
159         Assertions.assertNotNull(response);
160         Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
161         Mockito.verify(credsProvider).getCredentials(
162                 Mockito.eq(new AuthScope(target, "test realm", "basic")), Mockito.any());
163     }
164 
165     @Test
166     public void testBasicAuthenticationSuccess() throws Exception {
167         final H2TestServer server = startServer();
168         server.register("*", AsyncEchoHandler::new);
169         final HttpHost target = targetHost();
170 
171         final T client = startClient();
172 
173         final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
174         Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
175                 .thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
176         final HttpClientContext context = HttpClientContext.create();
177         context.setCredentialsProvider(credsProvider);
178 
179         final Future<SimpleHttpResponse> future = client.execute(
180                 SimpleRequestBuilder.get()
181                         .setHttpHost(target)
182                         .setPath("/")
183                         .build(), context, null);
184         final HttpResponse response = future.get();
185 
186         Assertions.assertNotNull(response);
187         Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
188         Mockito.verify(credsProvider).getCredentials(
189                 Mockito.eq(new AuthScope(target, "test realm", "basic")), Mockito.any());
190     }
191 
192     @Test
193     public void testBasicAuthenticationWithEntitySuccess() throws Exception {
194         final H2TestServer server = startServer();
195         server.register("*", AsyncEchoHandler::new);
196         final HttpHost target = targetHost();
197 
198         final T client = startClient();
199 
200         final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
201         Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
202                 .thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
203         final HttpClientContext context = HttpClientContext.create();
204         context.setCredentialsProvider(credsProvider);
205         final Future<SimpleHttpResponse> future = client.execute(
206                 SimpleRequestBuilder.put()
207                         .setHttpHost(target)
208                         .setPath("/")
209                         .setBody("Some important stuff", ContentType.TEXT_PLAIN)
210                         .build(), context, null);
211         final HttpResponse response = future.get();
212 
213         Assertions.assertNotNull(response);
214         Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
215         Mockito.verify(credsProvider).getCredentials(
216                 Mockito.eq(new AuthScope(target, "test realm", "basic")), Mockito.any());
217     }
218 
219     @Test
220     public void testBasicAuthenticationExpectationFailure() throws Exception {
221         final H2TestServer server = startServer();
222         server.register("*", AsyncEchoHandler::new);
223         final HttpHost target = targetHost();
224 
225         final T client = startClient();
226 
227         final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
228         Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
229                 .thenReturn(new UsernamePasswordCredentials("test", "all-wrong".toCharArray()));
230         final HttpClientContext context = HttpClientContext.create();
231         context.setCredentialsProvider(credsProvider);
232         context.setRequestConfig(RequestConfig.custom().setExpectContinueEnabled(true).build());
233         final Future<SimpleHttpResponse> future = client.execute(
234                 SimpleRequestBuilder.put()
235                         .setHttpHost(target)
236                         .setPath("/")
237                         .setBody("Some important stuff", ContentType.TEXT_PLAIN)
238                         .build(), context, null);
239         final HttpResponse response = future.get();
240 
241         Assertions.assertNotNull(response);
242         Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getCode());
243     }
244 
245     @Test
246     public void testBasicAuthenticationExpectationSuccess() throws Exception {
247         final H2TestServer server = startServer();
248         server.register("*", AsyncEchoHandler::new);
249         final HttpHost target = targetHost();
250 
251         final T client = startClient();
252 
253         final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
254         Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
255                 .thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
256         final HttpClientContext context = HttpClientContext.create();
257         context.setCredentialsProvider(credsProvider);
258         context.setRequestConfig(RequestConfig.custom().setExpectContinueEnabled(true).build());
259         final Future<SimpleHttpResponse> future = client.execute(
260                 SimpleRequestBuilder.put()
261                         .setHttpHost(target)
262                         .setPath("/")
263                         .setBody("Some important stuff", ContentType.TEXT_PLAIN)
264                         .build(), context, null);
265         final HttpResponse response = future.get();
266 
267         Assertions.assertNotNull(response);
268         Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
269         Mockito.verify(credsProvider).getCredentials(
270                 Mockito.eq(new AuthScope(target, "test realm", "basic")), Mockito.any());
271     }
272 
273     @Test
274     public void testBasicAuthenticationCredentialsCaching() throws Exception {
275         final H2TestServer server = startServer();
276         server.register("*", AsyncEchoHandler::new);
277         final HttpHost target = targetHost();
278 
279         final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
280         final T client = startClientCustom(builder ->  builder.setTargetAuthenticationStrategy(authStrategy));
281 
282         final HttpClientContext context = HttpClientContext.create();
283         context.setCredentialsProvider(CredentialsProviderBuilder.create()
284                 .add(target, "test", "test".toCharArray())
285                 .build());
286 
287         for (int i = 0; i < 5; i++) {
288             final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
289                     .setHttpHost(target)
290                     .setPath("/")
291                     .build(), context, null);
292             final HttpResponse response = future.get();
293             Assertions.assertNotNull(response);
294             Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
295         }
296 
297         Mockito.verify(authStrategy).select(Mockito.any(), Mockito.any(), Mockito.any());
298     }
299 
300     @Test
301     public void testBasicAuthenticationCredentialsCachingByPathPrefix() throws Exception {
302         final H2TestServer server = startServer();
303         server.register("*", AsyncEchoHandler::new);
304         final HttpHost target = targetHost();
305 
306         final DefaultAuthenticationStrategy authStrategy = Mockito.spy(new DefaultAuthenticationStrategy());
307         final Queue<HttpResponse> responseQueue = new ConcurrentLinkedQueue<>();
308 
309         final T client = startClientCustom(builder -> builder
310                 .setTargetAuthenticationStrategy(authStrategy)
311                 .addResponseInterceptor((response, entity, context)
312                         -> responseQueue.add(BasicResponseBuilder.copy(response).build())));
313 
314         final CredentialsProvider credentialsProvider = CredentialsProviderBuilder.create()
315                 .add(target, "test", "test".toCharArray())
316                 .build();
317 
318         final AuthCache authCache = new BasicAuthCache();
319 
320         for (final String requestPath: new String[] {"/blah/a", "/blah/b?huh", "/blah/c", "/bl%61h/%61"}) {
321             final HttpClientContext context = HttpClientContext.create();
322             context.setAuthCache(authCache);
323             context.setCredentialsProvider(credentialsProvider);
324             final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
325                     .setHttpHost(target)
326                     .setPath(requestPath)
327                     .build(), context, null);
328             final HttpResponse response = future.get();
329             Assertions.assertNotNull(response);
330             Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
331         }
332 
333         // There should be only single auth strategy call for all successful message exchanges
334         Mockito.verify(authStrategy).select(Mockito.any(), Mockito.any(), Mockito.any());
335 
336         assertThat(
337                 responseQueue.stream().map(HttpResponse::getCode).collect(Collectors.toList()),
338                 CoreMatchers.equalTo(Arrays.asList(401, 200, 200, 200, 200)));
339 
340         responseQueue.clear();
341         authCache.clear();
342         Mockito.reset(authStrategy);
343 
344         for (final String requestPath: new String[] {"/blah/a", "/yada/a", "/blah/blah/"}) {
345             final HttpClientContext context = HttpClientContext.create();
346             context.setCredentialsProvider(credentialsProvider);
347             context.setAuthCache(authCache);
348             final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
349                     .setHttpHost(target)
350                     .setPath(requestPath)
351                     .build(), context, null);
352             final HttpResponse response = future.get();
353             Assertions.assertNotNull(response);
354             Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
355         }
356 
357         // There should be an auth strategy call for all successful message exchanges
358         Mockito.verify(authStrategy, Mockito.times(3)).select(Mockito.any(), Mockito.any(), Mockito.any());
359 
360         assertThat(
361                 responseQueue.stream().map(HttpResponse::getCode).collect(Collectors.toList()),
362                 CoreMatchers.equalTo(Arrays.asList(401, 200, 401, 200, 401, 200)));
363     }
364 
365     @Test
366     public void testAuthenticationUserinfoInRequestFailure() throws Exception {
367         final H2TestServer server = startServer();
368         server.register("*", AsyncEchoHandler::new);
369         final HttpHost target = targetHost();
370 
371         final T client = startClient();
372 
373         final HttpClientContext context = HttpClientContext.create();
374         final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
375                         .setScheme(target.getSchemeName())
376                         .setAuthority(new URIAuthority("test:test", target.getHostName(), target.getPort()))
377                         .setPath("/")
378                         .build(), context, null);
379         final ExecutionException exception = Assertions.assertThrows(ExecutionException.class, () -> future.get());
380         assertThat(exception.getCause(), CoreMatchers.instanceOf(ProtocolException.class));
381     }
382 
383     @Test
384     public void testReauthentication() throws Exception {
385         final Authenticator authenticator = new BasicTestAuthenticator("test:test", "test realm") {
386 
387             private final AtomicLong count = new AtomicLong(0);
388 
389             @Override
390             public boolean authenticate(final URIAuthority authority, final String requestUri, final String credentials) {
391                 final boolean authenticated = super.authenticate(authority, requestUri, credentials);
392                 if (authenticated) {
393                     return this.count.incrementAndGet() % 4 != 0;
394                 }
395                 return false;
396             }
397         };
398 
399         final H2TestServer server = startServer(exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, authenticator) {
400 
401             @Override
402             protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
403                 unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
404                 unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
405             }
406 
407         });
408         server.register("*", AsyncEchoHandler::new);
409         final HttpHost target = targetHost();
410 
411         final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
412         Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
413                 .thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
414 
415         final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
416                 .register("MyBasic", context -> new BasicScheme() {
417 
418                     private static final long serialVersionUID = 1L;
419 
420                     @Override
421                     public String getName() {
422                         return "MyBasic";
423                     }
424 
425                 })
426                 .build();
427 
428         final T client = startClientCustom(builder -> builder.setDefaultAuthSchemeRegistry(authSchemeRegistry));
429 
430         final RequestConfig config = RequestConfig.custom()
431                 .setTargetPreferredAuthSchemes(Collections.singletonList("MyBasic"))
432                 .build();
433         final HttpClientContext context = HttpClientContext.create();
434         context.setCredentialsProvider(credsProvider);
435 
436         for (int i = 0; i < 10; i++) {
437             final SimpleHttpRequest request = SimpleRequestBuilder.get()
438                         .setHttpHost(target)
439                         .setPath("/")
440                         .build();
441             request.setConfig(config);
442             final Future<SimpleHttpResponse> future = client.execute(request, context, null);
443             final SimpleHttpResponse response = future.get();
444             Assertions.assertNotNull(response);
445             Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
446         }
447     }
448 
449     @Test
450     public void testAuthenticationFallback() throws Exception {
451         final H2TestServer server = startServer(exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
452 
453             @Override
454             protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
455                 unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
456             }
457 
458         });
459         server.register("*", AsyncEchoHandler::new);
460         final HttpHost target = targetHost();
461 
462         final T client = startClient();
463 
464         final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
465         Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
466                 .thenReturn(new UsernamePasswordCredentials("test", "test".toCharArray()));
467         final HttpClientContext context = HttpClientContext.create();
468         context.setCredentialsProvider(credsProvider);
469 
470         final Future<SimpleHttpResponse> future = client.execute(SimpleRequestBuilder.get()
471                         .setHttpHost(target)
472                         .setPath("/")
473                         .build(), context, null);
474         final SimpleHttpResponse response = future.get();
475         Assertions.assertNotNull(response);
476         Assertions.assertEquals(HttpStatus.SC_OK, response.getCode());
477         Mockito.verify(credsProvider).getCredentials(
478                 Mockito.eq(new AuthScope(target, "test realm", "basic")), Mockito.any());
479     }
480 
481     private final static String CHARS = "0123456789abcdef";
482 
483     @Test
484     public void testBearerTokenAuthentication() throws Exception {
485         final SecureRandom secureRandom = SecureRandom.getInstanceStrong();
486         secureRandom.setSeed(System.currentTimeMillis());
487         final StringBuilder buf = new StringBuilder();
488         for (int i = 0; i < 16; i++) {
489             buf.append(CHARS.charAt(secureRandom.nextInt(CHARS.length() - 1)));
490         }
491         final String token = buf.toString();
492         final H2TestServer server = startServer(requestHandler ->
493                 new AuthenticatingAsyncDecorator(
494                         requestHandler,
495                         new BearerAuthenticationHandler(),
496                         new BasicTestAuthenticator(token, "test realm")));
497         server.register("*", AsyncEchoHandler::new);
498         final HttpHost target = targetHost();
499 
500         final T client = startClient();
501 
502         final CredentialsProvider credsProvider = Mockito.mock(CredentialsProvider.class);
503         final HttpClientContext context1 = HttpClientContext.create();
504         context1.setCredentialsProvider(credsProvider);
505 
506         final Future<SimpleHttpResponse> future1 = client.execute(SimpleRequestBuilder.get()
507                 .setHttpHost(target)
508                 .setPath("/")
509                 .build(), context1, null);
510         final SimpleHttpResponse response1 = future1.get();
511         Assertions.assertNotNull(response1);
512         Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response1.getCode());
513         Mockito.verify(credsProvider).getCredentials(
514                 Mockito.eq(new AuthScope(target, "test realm", "bearer")), Mockito.any());
515 
516         final HttpClientContext context2 = HttpClientContext.create();
517         Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
518                 .thenReturn(new BearerToken(token));
519         context2.setCredentialsProvider(credsProvider);
520 
521         final Future<SimpleHttpResponse> future2 = client.execute(SimpleRequestBuilder.get()
522                 .setHttpHost(target)
523                 .setPath("/")
524                 .build(), context2, null);
525         final SimpleHttpResponse response2 = future2.get();
526         Assertions.assertNotNull(response2);
527         Assertions.assertEquals(HttpStatus.SC_OK, response2.getCode());
528 
529         final HttpClientContext context3 = HttpClientContext.create();
530         Mockito.when(credsProvider.getCredentials(Mockito.any(), Mockito.any()))
531                 .thenReturn(new BearerToken(token + "-expired"));
532         context3.setCredentialsProvider(credsProvider);
533 
534         final Future<SimpleHttpResponse> future3 = client.execute(SimpleRequestBuilder.get()
535                 .setHttpHost(target)
536                 .setPath("/")
537                 .build(), context3, null);
538         final SimpleHttpResponse response3 = future3.get();
539         Assertions.assertNotNull(response3);
540         Assertions.assertEquals(HttpStatus.SC_UNAUTHORIZED, response3.getCode());
541     }
542 
543 }