1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.http.impl.client.integration;
28
29 import java.io.ByteArrayInputStream;
30 import java.io.IOException;
31 import java.util.concurrent.atomic.AtomicLong;
32
33 import org.apache.http.Consts;
34 import org.apache.http.HttpEntity;
35 import org.apache.http.HttpException;
36 import org.apache.http.HttpHost;
37 import org.apache.http.HttpInetConnection;
38 import org.apache.http.HttpRequest;
39 import org.apache.http.HttpResponse;
40 import org.apache.http.HttpStatus;
41 import org.apache.http.auth.AUTH;
42 import org.apache.http.auth.AuthScope;
43 import org.apache.http.auth.Credentials;
44 import org.apache.http.auth.UsernamePasswordCredentials;
45 import org.apache.http.client.AuthCache;
46 import org.apache.http.client.ClientProtocolException;
47 import org.apache.http.client.CredentialsProvider;
48 import org.apache.http.client.NonRepeatableRequestException;
49 import org.apache.http.client.config.RequestConfig;
50 import org.apache.http.client.methods.HttpGet;
51 import org.apache.http.client.methods.HttpPost;
52 import org.apache.http.client.methods.HttpPut;
53 import org.apache.http.client.protocol.HttpClientContext;
54 import org.apache.http.entity.InputStreamEntity;
55 import org.apache.http.entity.StringEntity;
56 import org.apache.http.impl.auth.BasicScheme;
57 import org.apache.http.impl.client.BasicAuthCache;
58 import org.apache.http.impl.client.BasicCredentialsProvider;
59 import org.apache.http.impl.client.TargetAuthenticationStrategy;
60 import org.apache.http.localserver.BasicAuthTokenExtractor;
61 import org.apache.http.localserver.LocalServerTestBase;
62 import org.apache.http.localserver.RequestBasicAuth;
63 import org.apache.http.localserver.ResponseBasicUnauthorized;
64 import org.apache.http.message.BasicHeader;
65 import org.apache.http.protocol.HTTP;
66 import org.apache.http.protocol.HttpContext;
67 import org.apache.http.protocol.HttpCoreContext;
68 import org.apache.http.protocol.HttpExpectationVerifier;
69 import org.apache.http.protocol.HttpProcessor;
70 import org.apache.http.protocol.HttpProcessorBuilder;
71 import org.apache.http.protocol.HttpRequestHandler;
72 import org.apache.http.protocol.ResponseConnControl;
73 import org.apache.http.protocol.ResponseContent;
74 import org.apache.http.protocol.ResponseDate;
75 import org.apache.http.protocol.ResponseServer;
76 import org.apache.http.util.EntityUtils;
77 import org.junit.Assert;
78 import org.junit.Before;
79 import org.junit.Test;
80
81
82
83
84 public class TestClientAuthentication extends LocalServerTestBase {
85
86 @Before @Override
87 public void setUp() throws Exception {
88 super.setUp();
89 final HttpProcessor httpproc = HttpProcessorBuilder.create()
90 .add(new ResponseDate())
91 .add(new ResponseServer(LocalServerTestBase.ORIGIN))
92 .add(new ResponseContent())
93 .add(new ResponseConnControl())
94 .add(new RequestBasicAuth())
95 .add(new ResponseBasicUnauthorized()).build();
96 this.serverBootstrap.setHttpProcessor(httpproc);
97 }
98
99 static class AuthHandler implements HttpRequestHandler {
100
101 @Override
102 public void handle(
103 final HttpRequest request,
104 final HttpResponse response,
105 final HttpContext context) throws HttpException, IOException {
106 final String creds = (String) context.getAttribute("creds");
107 if (creds == null || !creds.equals("test:test")) {
108 response.setStatusCode(HttpStatus.SC_UNAUTHORIZED);
109 } else {
110 response.setStatusCode(HttpStatus.SC_OK);
111 final StringEntity entity = new StringEntity("success", Consts.ASCII);
112 response.setEntity(entity);
113 }
114 }
115
116 }
117
118 static class AuthExpectationVerifier implements HttpExpectationVerifier {
119
120 private final BasicAuthTokenExtractor authTokenExtractor;
121
122 public AuthExpectationVerifier() {
123 super();
124 this.authTokenExtractor = new BasicAuthTokenExtractor();
125 }
126
127 @Override
128 public void verify(
129 final HttpRequest request,
130 final HttpResponse response,
131 final HttpContext context) throws HttpException {
132 final String creds = this.authTokenExtractor.extract(request);
133 if (creds == null || !creds.equals("test:test")) {
134 response.setStatusCode(HttpStatus.SC_UNAUTHORIZED);
135 } else {
136 response.setStatusCode(HttpStatus.SC_CONTINUE);
137 }
138 }
139
140 }
141
142 static class TestCredentialsProvider implements CredentialsProvider {
143
144 private final Credentials creds;
145 private AuthScope authscope;
146
147 TestCredentialsProvider(final Credentials creds) {
148 super();
149 this.creds = creds;
150 }
151
152 @Override
153 public void clear() {
154 }
155
156 @Override
157 public Credentials getCredentials(final AuthScope authscope) {
158 this.authscope = authscope;
159 return this.creds;
160 }
161
162 @Override
163 public void setCredentials(final AuthScope authscope, final Credentials credentials) {
164 }
165
166 public AuthScope getAuthScope() {
167 return this.authscope;
168 }
169
170 }
171
172 @Test
173 public void testBasicAuthenticationNoCreds() throws Exception {
174 this.serverBootstrap.registerHandler("*", new AuthHandler());
175
176 final HttpHost target = start();
177
178 final HttpClientContext context = HttpClientContext.create();
179 final TestCredentialsProvider credsProvider = new TestCredentialsProvider(null);
180 context.setCredentialsProvider(credsProvider);
181 final HttpGet httpget = new HttpGet("/");
182
183 final HttpResponse response = this.httpclient.execute(target, httpget, context);
184 final HttpEntity entity = response.getEntity();
185 Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode());
186 Assert.assertNotNull(entity);
187 EntityUtils.consume(entity);
188 final AuthScope authscope = credsProvider.getAuthScope();
189 Assert.assertNotNull(authscope);
190 Assert.assertEquals("test realm", authscope.getRealm());
191 }
192
193 @Test
194 public void testBasicAuthenticationFailure() throws Exception {
195 this.serverBootstrap.registerHandler("*", new AuthHandler());
196
197 final HttpHost target = start();
198
199 final HttpClientContext context = HttpClientContext.create();
200 final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
201 new UsernamePasswordCredentials("test", "all-wrong"));
202 context.setCredentialsProvider(credsProvider);
203 final HttpGet httpget = new HttpGet("/");
204
205 final HttpResponse response = this.httpclient.execute(target, httpget, context);
206 final HttpEntity entity = response.getEntity();
207 Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode());
208 Assert.assertNotNull(entity);
209 EntityUtils.consume(entity);
210 final AuthScope authscope = credsProvider.getAuthScope();
211 Assert.assertNotNull(authscope);
212 Assert.assertEquals("test realm", authscope.getRealm());
213 }
214
215 @Test
216 public void testBasicAuthenticationSuccess() throws Exception {
217 this.serverBootstrap.registerHandler("*", new AuthHandler());
218
219 final HttpGet httpget = new HttpGet("/");
220 final HttpClientContext context = HttpClientContext.create();
221 final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
222 new UsernamePasswordCredentials("test", "test"));
223 context.setCredentialsProvider(credsProvider);
224
225 final HttpHost target = start();
226
227 final HttpResponse response = this.httpclient.execute(target, httpget, context);
228 final HttpEntity entity = response.getEntity();
229 Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
230 Assert.assertNotNull(entity);
231 EntityUtils.consume(entity);
232 final AuthScope authscope = credsProvider.getAuthScope();
233 Assert.assertNotNull(authscope);
234 Assert.assertEquals("test realm", authscope.getRealm());
235 }
236
237 @Test
238 public void testBasicAuthenticationSuccessOnNonRepeatablePutExpectContinue() throws Exception {
239 final HttpProcessor httpproc = HttpProcessorBuilder.create()
240 .add(new ResponseDate())
241 .add(new ResponseServer(LocalServerTestBase.ORIGIN))
242 .add(new ResponseContent())
243 .add(new ResponseConnControl())
244 .add(new RequestBasicAuth())
245 .add(new ResponseBasicUnauthorized()).build();
246 this.serverBootstrap.setHttpProcessor(httpproc)
247 .setExpectationVerifier(new AuthExpectationVerifier())
248 .registerHandler("*", new AuthHandler());
249
250 final HttpHost target = start();
251
252 final RequestConfig config = RequestConfig.custom()
253 .setExpectContinueEnabled(true)
254 .build();
255 final HttpPut httpput = new HttpPut("/");
256 httpput.setConfig(config);
257 httpput.setEntity(new InputStreamEntity(
258 new ByteArrayInputStream(
259 new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ),
260 -1));
261 final HttpClientContext context = HttpClientContext.create();
262 final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
263 new UsernamePasswordCredentials("test", "test"));
264 context.setCredentialsProvider(credsProvider);
265
266 final HttpResponse response = this.httpclient.execute(target, httpput, context);
267 final HttpEntity entity = response.getEntity();
268 Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
269 Assert.assertNotNull(entity);
270 }
271
272 @Test(expected=ClientProtocolException.class)
273 public void testBasicAuthenticationFailureOnNonRepeatablePutDontExpectContinue() throws Exception {
274 this.serverBootstrap.registerHandler("*", new AuthHandler());
275
276 final HttpHost target = start();
277
278 final RequestConfig config = RequestConfig.custom().setExpectContinueEnabled(true).build();
279 final HttpPut httpput = new HttpPut("/");
280 httpput.setConfig(config);
281 httpput.setEntity(new InputStreamEntity(
282 new ByteArrayInputStream(
283 new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ),
284 -1));
285
286 final HttpClientContext context = HttpClientContext.create();
287 final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
288 new UsernamePasswordCredentials("test", "boom"));
289 context.setCredentialsProvider(credsProvider);
290
291 try {
292 this.httpclient.execute(target, httpput, context);
293 Assert.fail("ClientProtocolException should have been thrown");
294 } catch (final ClientProtocolException ex) {
295 final Throwable cause = ex.getCause();
296 Assert.assertNotNull(cause);
297 Assert.assertTrue(cause instanceof NonRepeatableRequestException);
298 throw ex;
299 }
300 }
301
302 @Test
303 public void testBasicAuthenticationSuccessOnRepeatablePost() throws Exception {
304 this.serverBootstrap.registerHandler("*", new AuthHandler());
305
306 final HttpHost target = start();
307
308 final HttpPost httppost = new HttpPost("/");
309 httppost.setEntity(new StringEntity("some important stuff", Consts.ASCII));
310
311 final HttpClientContext context = HttpClientContext.create();
312 final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
313 new UsernamePasswordCredentials("test", "test"));
314 context.setCredentialsProvider(credsProvider);
315
316 final HttpResponse response = this.httpclient.execute(target, httppost, context);
317 final HttpEntity entity = response.getEntity();
318 Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
319 Assert.assertNotNull(entity);
320 EntityUtils.consume(entity);
321 final AuthScope authscope = credsProvider.getAuthScope();
322 Assert.assertNotNull(authscope);
323 Assert.assertEquals("test realm", authscope.getRealm());
324 }
325
326 @Test(expected=ClientProtocolException.class)
327 public void testBasicAuthenticationFailureOnNonRepeatablePost() throws Exception {
328 this.serverBootstrap.registerHandler("*", new AuthHandler());
329
330 final HttpHost target = start();
331
332 final HttpPost httppost = new HttpPost("/");
333 httppost.setEntity(new InputStreamEntity(
334 new ByteArrayInputStream(
335 new byte[] { 0,1,2,3,4,5,6,7,8,9 }), -1));
336
337 final HttpClientContext context = HttpClientContext.create();
338 final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
339 new UsernamePasswordCredentials("test", "test"));
340 context.setCredentialsProvider(credsProvider);
341
342 try {
343 this.httpclient.execute(target, httppost, context);
344 Assert.fail("ClientProtocolException should have been thrown");
345 } catch (final ClientProtocolException ex) {
346 final Throwable cause = ex.getCause();
347 Assert.assertNotNull(cause);
348 Assert.assertTrue(cause instanceof NonRepeatableRequestException);
349 throw ex;
350 }
351 }
352
353 static class TestTargetAuthenticationStrategy extends TargetAuthenticationStrategy {
354
355 private final AtomicLong count;
356
357 public TestTargetAuthenticationStrategy() {
358 super();
359 this.count = new AtomicLong();
360 }
361
362 @Override
363 public boolean isAuthenticationRequested(
364 final HttpHost host,
365 final HttpResponse response,
366 final HttpContext context) {
367 final boolean res = super.isAuthenticationRequested(host, response, context);
368 if (res == true) {
369 this.count.incrementAndGet();
370 }
371 return res;
372 }
373
374 public long getCount() {
375 return this.count.get();
376 }
377
378 }
379
380 @Test
381 public void testBasicAuthenticationCredentialsCaching() throws Exception {
382 this.serverBootstrap.registerHandler("*", new AuthHandler());
383
384 final TestTargetAuthenticationStrategy authStrategy = new TestTargetAuthenticationStrategy();
385 this.clientBuilder.setTargetAuthenticationStrategy(authStrategy);
386
387 final HttpHost target = start();
388
389 final HttpClientContext context = HttpClientContext.create();
390 final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
391 credsProvider.setCredentials(AuthScope.ANY,
392 new UsernamePasswordCredentials("test", "test"));
393 context.setCredentialsProvider(credsProvider);
394
395 final HttpGet httpget = new HttpGet("/");
396
397 final HttpResponse response1 = this.httpclient.execute(target, httpget, context);
398 final HttpEntity entity1 = response1.getEntity();
399 Assert.assertEquals(HttpStatus.SC_OK, response1.getStatusLine().getStatusCode());
400 Assert.assertNotNull(entity1);
401 EntityUtils.consume(entity1);
402
403 final HttpResponse response2 = this.httpclient.execute(target, httpget, context);
404 final HttpEntity entity2 = response1.getEntity();
405 Assert.assertEquals(HttpStatus.SC_OK, response2.getStatusLine().getStatusCode());
406 Assert.assertNotNull(entity2);
407 EntityUtils.consume(entity2);
408
409 Assert.assertEquals(1, authStrategy.getCount());
410 }
411
412 static class RealmAuthHandler implements HttpRequestHandler {
413
414 final String realm;
415 final String realmCreds;
416
417 public RealmAuthHandler(final String realm, final String realmCreds) {
418 this.realm = realm;
419 this.realmCreds = realmCreds;
420 }
421
422 @Override
423 public void handle(
424 final HttpRequest request,
425 final HttpResponse response,
426 final HttpContext context) throws HttpException, IOException {
427 final String givenCreds = (String) context.getAttribute("creds");
428 if (givenCreds == null || !givenCreds.equals(this.realmCreds)) {
429 response.setStatusCode(HttpStatus.SC_UNAUTHORIZED);
430 response.addHeader(AUTH.WWW_AUTH, "Basic realm=\"" + this.realm + "\"");
431 } else {
432 response.setStatusCode(HttpStatus.SC_OK);
433 final StringEntity entity = new StringEntity("success", Consts.ASCII);
434 response.setEntity(entity);
435 }
436 }
437
438 }
439
440 @Test
441 public void testAuthenticationCredentialsCachingReauthenticationOnDifferentRealm() throws Exception {
442 this.serverBootstrap.registerHandler("/this", new RealmAuthHandler("this realm", "test:this"));
443 this.serverBootstrap.registerHandler("/that", new RealmAuthHandler("that realm", "test:that"));
444
445 this.server = this.serverBootstrap.create();
446 this.server.start();
447
448 final HttpHost target = new HttpHost("localhost", this.server.getLocalPort(), this.scheme.name());
449
450 final TestTargetAuthenticationStrategy authStrategy = new TestTargetAuthenticationStrategy();
451 final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
452 credsProvider.setCredentials(new AuthScope(target, "this realm", null),
453 new UsernamePasswordCredentials("test", "this"));
454 credsProvider.setCredentials(new AuthScope(target, "that realm", null),
455 new UsernamePasswordCredentials("test", "that"));
456
457 this.clientBuilder.setTargetAuthenticationStrategy(authStrategy);
458 this.httpclient = this.clientBuilder.build();
459
460 final HttpClientContext context = HttpClientContext.create();
461 context.setCredentialsProvider(credsProvider);
462
463 final HttpGet httpget1 = new HttpGet("/this");
464
465 final HttpResponse response1 = this.httpclient.execute(target, httpget1, context);
466 final HttpEntity entity1 = response1.getEntity();
467 Assert.assertEquals(HttpStatus.SC_OK, response1.getStatusLine().getStatusCode());
468 Assert.assertNotNull(entity1);
469 EntityUtils.consume(entity1);
470
471 final HttpGet httpget2 = new HttpGet("/this");
472
473 final HttpResponse response2 = this.httpclient.execute(target, httpget2, context);
474 final HttpEntity entity2 = response1.getEntity();
475 Assert.assertEquals(HttpStatus.SC_OK, response2.getStatusLine().getStatusCode());
476 Assert.assertNotNull(entity2);
477 EntityUtils.consume(entity2);
478
479 final HttpGet httpget3 = new HttpGet("/that");
480
481 final HttpResponse response3 = this.httpclient.execute(target, httpget3, context);
482 final HttpEntity entity3 = response1.getEntity();
483 Assert.assertEquals(HttpStatus.SC_OK, response3.getStatusLine().getStatusCode());
484 Assert.assertNotNull(entity3);
485 EntityUtils.consume(entity3);
486
487 Assert.assertEquals(2, authStrategy.getCount());
488 }
489
490 @Test
491 public void testAuthenticationUserinfoInRequestSuccess() throws Exception {
492 this.serverBootstrap.registerHandler("*", new AuthHandler());
493
494 final HttpHost target = start();
495 final HttpGet httpget = new HttpGet("http://test:test@" + target.toHostString() + "/");
496
497 final HttpClientContext context = HttpClientContext.create();
498 final HttpResponse response = this.httpclient.execute(target, httpget, context);
499 final HttpEntity entity = response.getEntity();
500 Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
501 Assert.assertNotNull(entity);
502 EntityUtils.consume(entity);
503 }
504
505 @Test
506 public void testAuthenticationUserinfoInRequestFailure() throws Exception {
507 this.serverBootstrap.registerHandler("*", new AuthHandler());
508
509 final HttpHost target = start();
510 final HttpGet httpget = new HttpGet("http://test:all-wrong@" + target.toHostString() + "/");
511
512 final HttpClientContext context = HttpClientContext.create();
513 final HttpResponse response = this.httpclient.execute(target, httpget, context);
514 final HttpEntity entity = response.getEntity();
515 Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response.getStatusLine().getStatusCode());
516 Assert.assertNotNull(entity);
517 EntityUtils.consume(entity);
518 }
519
520 private static class RedirectHandler implements HttpRequestHandler {
521
522 public RedirectHandler() {
523 super();
524 }
525
526 @Override
527 public void handle(
528 final HttpRequest request,
529 final HttpResponse response,
530 final HttpContext context) throws HttpException, IOException {
531 final HttpInetConnection conn = (HttpInetConnection) context.getAttribute(HttpCoreContext.HTTP_CONNECTION);
532 final String localhost = conn.getLocalAddress().getHostName();
533 final int port = conn.getLocalPort();
534 response.setStatusCode(HttpStatus.SC_MOVED_PERMANENTLY);
535 response.addHeader(new BasicHeader("Location",
536 "http://test:test@" + localhost + ":" + port + "/"));
537 }
538
539 }
540
541 @Test
542 public void testAuthenticationUserinfoInRedirectSuccess() throws Exception {
543 this.serverBootstrap.registerHandler("*", new AuthHandler());
544 this.serverBootstrap.registerHandler("/thatway", new RedirectHandler());
545
546 final HttpHost target = start();
547
548 final HttpGet httpget = new HttpGet("http://" + target.toHostString() + "/thatway");
549 final HttpClientContext context = HttpClientContext.create();
550
551 final HttpResponse response = this.httpclient.execute(target, httpget, context);
552 final HttpEntity entity = response.getEntity();
553 Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
554 Assert.assertNotNull(entity);
555 EntityUtils.consume(entity);
556 }
557
558 static class CountingAuthHandler implements HttpRequestHandler {
559
560 private final AtomicLong count;
561
562 public CountingAuthHandler() {
563 super();
564 this.count = new AtomicLong();
565 }
566
567 @Override
568 public void handle(
569 final HttpRequest request,
570 final HttpResponse response,
571 final HttpContext context) throws HttpException, IOException {
572 this.count.incrementAndGet();
573 final String creds = (String) context.getAttribute("creds");
574 if (creds == null || !creds.equals("test:test")) {
575 response.setStatusCode(HttpStatus.SC_UNAUTHORIZED);
576 } else {
577 response.setStatusCode(HttpStatus.SC_OK);
578 final StringEntity entity = new StringEntity("success", Consts.ASCII);
579 response.setEntity(entity);
580 }
581 }
582
583 public long getCount() {
584 return this.count.get();
585 }
586
587 }
588
589 @Test
590 public void testPreemptiveAuthentication() throws Exception {
591 final CountingAuthHandler requestHandler = new CountingAuthHandler();
592 this.serverBootstrap.registerHandler("*", requestHandler);
593
594 final HttpHost target = start();
595
596 final HttpClientContext context = HttpClientContext.create();
597 final AuthCache authCache = new BasicAuthCache();
598 authCache.put(target, new BasicScheme());
599 context.setAuthCache(authCache);
600 final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
601 credsProvider.setCredentials(AuthScope.ANY,
602 new UsernamePasswordCredentials("test", "test"));
603 context.setCredentialsProvider(credsProvider);
604
605 final HttpGet httpget = new HttpGet("/");
606 final HttpResponse response1 = this.httpclient.execute(target, httpget, context);
607 final HttpEntity entity1 = response1.getEntity();
608 Assert.assertEquals(HttpStatus.SC_OK, response1.getStatusLine().getStatusCode());
609 Assert.assertNotNull(entity1);
610 EntityUtils.consume(entity1);
611
612 Assert.assertEquals(1, requestHandler.getCount());
613 }
614
615 @Test
616 public void testPreemptiveAuthenticationFailure() throws Exception {
617 final CountingAuthHandler requestHandler = new CountingAuthHandler();
618 this.serverBootstrap.registerHandler("*", requestHandler);
619
620 final HttpHost target = start();
621
622 final HttpClientContext context = HttpClientContext.create();
623 final AuthCache authCache = new BasicAuthCache();
624 authCache.put(target, new BasicScheme());
625 context.setAuthCache(authCache);
626 final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
627 credsProvider.setCredentials(AuthScope.ANY,
628 new UsernamePasswordCredentials("test", "stuff"));
629 context.setCredentialsProvider(credsProvider);
630
631 final HttpGet httpget = new HttpGet("/");
632 final HttpResponse response1 = this.httpclient.execute(target, httpget, context);
633 final HttpEntity entity1 = response1.getEntity();
634 Assert.assertEquals(HttpStatus.SC_UNAUTHORIZED, response1.getStatusLine().getStatusCode());
635 Assert.assertNotNull(entity1);
636 EntityUtils.consume(entity1);
637
638 Assert.assertEquals(1, requestHandler.getCount());
639 }
640
641 static class ProxyAuthHandler implements HttpRequestHandler {
642
643 @Override
644 public void handle(
645 final HttpRequest request,
646 final HttpResponse response,
647 final HttpContext context) throws HttpException, IOException {
648 final String creds = (String) context.getAttribute("creds");
649 if (creds == null || !creds.equals("test:test")) {
650 response.setStatusCode(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED);
651 } else {
652 response.setStatusCode(HttpStatus.SC_OK);
653 final StringEntity entity = new StringEntity("success", Consts.ASCII);
654 response.setEntity(entity);
655 }
656 }
657
658 }
659
660 @Test
661 public void testAuthenticationTargetAsProxy() throws Exception {
662 this.serverBootstrap.registerHandler("*", new ProxyAuthHandler());
663
664 final HttpHost target = start();
665
666 final HttpClientContext context = HttpClientContext.create();
667 final TestCredentialsProvider credsProvider = new TestCredentialsProvider(null);
668 context.setCredentialsProvider(credsProvider);
669
670 final HttpGet httpget = new HttpGet("/");
671 final HttpResponse response = this.httpclient.execute(target, httpget, context);
672 final HttpEntity entity = response.getEntity();
673 Assert.assertEquals(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED,
674 response.getStatusLine().getStatusCode());
675 EntityUtils.consume(entity);
676 }
677
678 static class ClosingAuthHandler implements HttpRequestHandler {
679
680 @Override
681 public void handle(
682 final HttpRequest request,
683 final HttpResponse response,
684 final HttpContext context) throws HttpException, IOException {
685 final String creds = (String) context.getAttribute("creds");
686 if (creds == null || !creds.equals("test:test")) {
687 response.setStatusCode(HttpStatus.SC_UNAUTHORIZED);
688 } else {
689 response.setStatusCode(HttpStatus.SC_OK);
690 final StringEntity entity = new StringEntity("success", Consts.ASCII);
691 response.setEntity(entity);
692 response.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);
693 }
694 }
695
696 }
697
698 @Test
699 public void testConnectionCloseAfterAuthenticationSuccess() throws Exception {
700 this.serverBootstrap.registerHandler("*", new ClosingAuthHandler());
701
702 final HttpHost target = start();
703
704 final HttpClientContext context = HttpClientContext.create();
705 final BasicCredentialsProvider credsProvider = new BasicCredentialsProvider();
706 credsProvider.setCredentials(AuthScope.ANY,
707 new UsernamePasswordCredentials("test", "test"));
708 context.setCredentialsProvider(credsProvider);
709
710 for (int i = 0; i < 2; i++) {
711 final HttpGet httpget = new HttpGet("/");
712
713 final HttpResponse response = this.httpclient.execute(target, httpget, context);
714 EntityUtils.consume(response.getEntity());
715 Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
716 }
717 }
718
719 }