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.http.impl.client;
28  
29  import java.util.Arrays;
30  import java.util.HashMap;
31  import java.util.Map;
32  import java.util.Queue;
33  
34  import org.apache.http.Header;
35  import org.apache.http.HttpHost;
36  import org.apache.http.HttpResponse;
37  import org.apache.http.HttpStatus;
38  import org.apache.http.HttpVersion;
39  import org.apache.http.auth.AUTH;
40  import org.apache.http.auth.AuthOption;
41  import org.apache.http.auth.AuthScheme;
42  import org.apache.http.auth.AuthSchemeProvider;
43  import org.apache.http.auth.AuthScope;
44  import org.apache.http.auth.UsernamePasswordCredentials;
45  import org.apache.http.client.AuthCache;
46  import org.apache.http.client.CredentialsProvider;
47  import org.apache.http.client.config.AuthSchemes;
48  import org.apache.http.client.config.RequestConfig;
49  import org.apache.http.client.protocol.HttpClientContext;
50  import org.apache.http.config.Registry;
51  import org.apache.http.config.RegistryBuilder;
52  import org.apache.http.impl.auth.BasicScheme;
53  import org.apache.http.impl.auth.BasicSchemeFactory;
54  import org.apache.http.impl.auth.DigestScheme;
55  import org.apache.http.impl.auth.DigestSchemeFactory;
56  import org.apache.http.message.BasicHeader;
57  import org.apache.http.message.BasicHttpResponse;
58  import org.junit.Assert;
59  import org.junit.Test;
60  import org.mockito.Mockito;
61  
62  /**
63   * Simple tests for {@link AuthenticationStrategyImpl}.
64   */
65  @SuppressWarnings("boxing") // test code
66  public class TestAuthenticationStrategy {
67  
68      @Test(expected=IllegalArgumentException.class)
69      public void testIsAuthenticationRequestedInvalidInput() throws Exception {
70          final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
71          final HttpHost host = new HttpHost("localhost", 80);
72          final HttpClientContext context = HttpClientContext.create();
73          authStrategy.isAuthenticationRequested(host, null, context);
74      }
75  
76      @Test
77      public void testTargetAuthRequested() throws Exception {
78          final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
79          final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
80          final HttpHost host = new HttpHost("localhost", 80);
81          final HttpClientContext context = HttpClientContext.create();
82          Assert.assertTrue(authStrategy.isAuthenticationRequested(host, response, context));
83      }
84  
85      @Test
86      public void testProxyAuthRequested() throws Exception {
87          final ProxyAuthenticationStrategy authStrategy = new ProxyAuthenticationStrategy();
88          final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, "UNAUTHORIZED");
89          final HttpHost host = new HttpHost("localhost", 80);
90          final HttpClientContext context = HttpClientContext.create();
91          Assert.assertTrue(authStrategy.isAuthenticationRequested(host, response, context));
92      }
93  
94      @Test(expected=IllegalArgumentException.class)
95      public void testGetChallengesInvalidInput() throws Exception {
96          final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
97          final HttpHost host = new HttpHost("localhost", 80);
98          final HttpClientContext context = HttpClientContext.create();
99          authStrategy.getChallenges(host, null, context);
100     }
101 
102     @Test
103     public void testGetChallenges() throws Exception {
104         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
105         final HttpClientContext context = HttpClientContext.create();
106         final HttpHost host = new HttpHost("localhost", 80);
107         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
108         final Header h1 = new BasicHeader(AUTH.WWW_AUTH, "  Basic  realm=\"test\"");
109         final Header h2 = new BasicHeader(AUTH.WWW_AUTH, "\t\tDigest   realm=\"realm1\", nonce=\"1234\"");
110         final Header h3 = new BasicHeader(AUTH.WWW_AUTH, "WhatEver realm=\"realm1\", stuff=\"1234\"");
111         response.addHeader(h1);
112         response.addHeader(h2);
113         response.addHeader(h3);
114 
115         final Map<String, Header> challenges = authStrategy.getChallenges(host, response, context);
116 
117         Assert.assertNotNull(challenges);
118         Assert.assertEquals(3, challenges.size());
119         Assert.assertSame(h1, challenges.get("basic"));
120         Assert.assertSame(h2, challenges.get("digest"));
121         Assert.assertSame(h3, challenges.get("whatever"));
122     }
123 
124     @Test
125     public void testSelectInvalidInput() throws Exception {
126         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
127         final Map<String, Header> challenges = new HashMap<String, Header>();
128         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
129         final HttpHost authhost = new HttpHost("locahost", 80);
130         final HttpClientContext context = HttpClientContext.create();
131         try {
132             authStrategy.select(null, authhost, response, context);
133             Assert.fail("IllegalArgumentException expected");
134         } catch (final IllegalArgumentException ex) {
135         }
136         try {
137             authStrategy.select(challenges, null, response, context);
138             Assert.fail("IllegalArgumentException expected");
139         } catch (final IllegalArgumentException ex) {
140         }
141         try {
142             authStrategy.select(challenges, authhost, null, context);
143             Assert.fail("IllegalArgumentException expected");
144         } catch (final IllegalArgumentException ex) {
145         }
146         try {
147             authStrategy.select(challenges, authhost, response, null);
148             Assert.fail("IllegalArgumentException expected");
149         } catch (final IllegalArgumentException ex) {
150         }
151     }
152 
153     @Test
154     public void testSelectNoSchemeRegistry() throws Exception {
155         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
156         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
157         final HttpHost authhost = new HttpHost("locahost", 80);
158         final HttpClientContext context = HttpClientContext.create();
159 
160         final Map<String, Header> challenges = new HashMap<String, Header>();
161         challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\""));
162         challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\""));
163 
164         final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
165         Assert.assertNotNull(options);
166         Assert.assertEquals(0, options.size());
167     }
168 
169     @Test
170     public void testSelectNoCredentialsProvider() throws Exception {
171         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
172         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
173         final HttpHost authhost = new HttpHost("locahost", 80);
174         final HttpClientContext context = HttpClientContext.create();
175 
176         final Map<String, Header> challenges = new HashMap<String, Header>();
177         challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"test\""));
178         challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\""));
179 
180         final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
181             .register("basic", new BasicSchemeFactory())
182             .register("digest", new DigestSchemeFactory()).build();
183         context.setAuthSchemeRegistry(authSchemeRegistry);
184 
185         final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
186         Assert.assertNotNull(options);
187         Assert.assertEquals(0, options.size());
188     }
189 
190     @Test
191     public void testNoCredentials() throws Exception {
192         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
193         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
194         final HttpHost authhost = new HttpHost("locahost", 80);
195         final HttpClientContext context = HttpClientContext.create();
196 
197         final Map<String, Header> challenges = new HashMap<String, Header>();
198         challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\""));
199         challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\""));
200 
201         final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
202             .register("basic", new BasicSchemeFactory())
203             .register("digest", new DigestSchemeFactory()).build();
204         context.setAuthSchemeRegistry(authSchemeRegistry);
205 
206         final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
207         context.setCredentialsProvider(credentialsProvider);
208 
209         final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
210         Assert.assertNotNull(options);
211         Assert.assertEquals(0, options.size());
212     }
213 
214     @Test
215     public void testCredentialsFound() throws Exception {
216         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
217         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
218         final HttpHost authhost = new HttpHost("somehost", 80);
219         final HttpClientContext context = HttpClientContext.create();
220 
221         final Map<String, Header> challenges = new HashMap<String, Header>();
222         challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\""));
223         challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\""));
224 
225         final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
226             .register("basic", new BasicSchemeFactory())
227             .register("digest", new DigestSchemeFactory()).build();
228         context.setAuthSchemeRegistry(authSchemeRegistry);
229 
230         final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
231         credentialsProvider.setCredentials(new AuthScope("somehost", 80, "realm2"),
232                 new UsernamePasswordCredentials("user", "pwd"));
233         context.setCredentialsProvider(credentialsProvider);
234 
235         final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
236         Assert.assertNotNull(options);
237         Assert.assertEquals(1, options.size());
238         final AuthOption option = options.remove();
239         Assert.assertTrue(option.getAuthScheme() instanceof DigestScheme);
240     }
241 
242     @Test
243     public void testUnsupportedScheme() throws Exception {
244         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
245         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
246         final HttpHost authhost = new HttpHost("somehost", 80);
247         final HttpClientContext context = HttpClientContext.create();
248 
249         final Map<String, Header> challenges = new HashMap<String, Header>();
250         challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\""));
251         challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\""));
252         challenges.put("whatever", new BasicHeader(AUTH.WWW_AUTH, "Whatever realm=\"realm3\""));
253 
254         final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
255             .register("basic", new BasicSchemeFactory())
256             .register("digest", new DigestSchemeFactory()).build();
257         context.setAuthSchemeRegistry(authSchemeRegistry);
258 
259         final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
260         credentialsProvider.setCredentials(new AuthScope("somehost", 80),
261                 new UsernamePasswordCredentials("user", "pwd"));
262         context.setCredentialsProvider(credentialsProvider);
263 
264         final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
265         Assert.assertNotNull(options);
266         Assert.assertEquals(2, options.size());
267         final AuthOption option1 = options.remove();
268         Assert.assertTrue(option1.getAuthScheme() instanceof DigestScheme);
269         final AuthOption option2 = options.remove();
270         Assert.assertTrue(option2.getAuthScheme() instanceof BasicScheme);
271     }
272 
273     @Test
274     public void testCustomAuthPreference() throws Exception {
275         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
276         final HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
277         final RequestConfig config = RequestConfig.custom()
278             .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC))
279             .build();
280 
281         final HttpHost authhost = new HttpHost("somehost", 80);
282         final HttpClientContext context = HttpClientContext.create();
283 
284         final Map<String, Header> challenges = new HashMap<String, Header>();
285         challenges.put("basic", new BasicHeader(AUTH.WWW_AUTH, "Basic realm=\"realm1\""));
286         challenges.put("digest", new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm2\", nonce=\"1234\""));
287 
288         final Registry<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
289             .register("basic", new BasicSchemeFactory())
290             .register("digest", new DigestSchemeFactory()).build();
291         context.setAuthSchemeRegistry(authSchemeRegistry);
292         context.setRequestConfig(config);
293 
294         final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
295         credentialsProvider.setCredentials(new AuthScope("somehost", 80),
296                 new UsernamePasswordCredentials("user", "pwd"));
297         context.setCredentialsProvider(credentialsProvider);
298 
299         final Queue<AuthOption> options = authStrategy.select(challenges, authhost, response, context);
300         Assert.assertNotNull(options);
301         Assert.assertEquals(1, options.size());
302         final AuthOption option1 = options.remove();
303         Assert.assertTrue(option1.getAuthScheme() instanceof BasicScheme);
304     }
305 
306     @Test
307     public void testAuthSucceededInvalidInput() throws Exception {
308         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
309         final HttpHost authhost = new HttpHost("locahost", 80);
310         final BasicScheme authScheme = new BasicScheme();
311         final HttpClientContext context = HttpClientContext.create();
312         try {
313             authStrategy.authSucceeded(null, authScheme, context);
314             Assert.fail("IllegalArgumentException expected");
315         } catch (final IllegalArgumentException ex) {
316         }
317         try {
318             authStrategy.authSucceeded(authhost, null, context);
319             Assert.fail("IllegalArgumentException expected");
320         } catch (final IllegalArgumentException ex) {
321         }
322         try {
323             authStrategy.authSucceeded(authhost, authScheme, null);
324             Assert.fail("IllegalArgumentException expected");
325         } catch (final IllegalArgumentException ex) {
326         }
327     }
328 
329     @Test
330     public void testAuthSucceeded() throws Exception {
331         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
332         final HttpHost authhost = new HttpHost("somehost", 80);
333         final BasicScheme authScheme = new BasicScheme();
334         authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test"));
335 
336         final AuthCache authCache = Mockito.mock(AuthCache.class);
337 
338         final HttpClientContext context = HttpClientContext.create();
339         context.setAuthCache(authCache);
340 
341         authStrategy.authSucceeded(authhost, authScheme, context);
342         Mockito.verify(authCache).put(authhost, authScheme);
343     }
344 
345     @Test
346     public void testAuthSucceededNoCache() throws Exception {
347         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
348         final HttpHost authhost = new HttpHost("somehost", 80);
349         final BasicScheme authScheme = new BasicScheme();
350         authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test"));
351 
352         final HttpClientContext context = HttpClientContext.create();
353         context.setAuthCache(null);
354 
355         authStrategy.authSucceeded(authhost, authScheme, context);
356         final AuthCache authCache = context.getAuthCache();
357         Assert.assertNotNull(authCache);
358     }
359 
360     @Test
361     public void testAuthScemeNotCompleted() throws Exception {
362         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
363         final HttpHost authhost = new HttpHost("somehost", 80);
364         final BasicScheme authScheme = new BasicScheme();
365 
366         final AuthCache authCache = Mockito.mock(AuthCache.class);
367 
368         final HttpClientContext context = HttpClientContext.create();
369         context.setAuthCache(authCache);
370 
371         authStrategy.authSucceeded(authhost, authScheme, context);
372         Mockito.verify(authCache, Mockito.never()).put(authhost, authScheme);
373     }
374 
375     @Test
376     public void testAuthScemeNonCacheable() throws Exception {
377         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
378         final HttpHost authhost = new HttpHost("somehost", 80);
379         final AuthScheme authScheme = Mockito.mock(AuthScheme.class);
380         Mockito.when(authScheme.isComplete()).thenReturn(true);
381         Mockito.when(authScheme.getSchemeName()).thenReturn("whatever");
382 
383         final AuthCache authCache = Mockito.mock(AuthCache.class);
384 
385         final HttpClientContext context = HttpClientContext.create();
386         context.setAuthCache(authCache);
387 
388         authStrategy.authSucceeded(authhost, authScheme, context);
389         Mockito.verify(authCache, Mockito.never()).put(authhost, authScheme);
390     }
391 
392     @Test
393     public void testAuthFailedInvalidInput() throws Exception {
394         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
395         final HttpHost authhost = new HttpHost("locahost", 80);
396         final BasicScheme authScheme = new BasicScheme();
397         final HttpClientContext context = HttpClientContext.create();
398         try {
399             authStrategy.authFailed(null, authScheme, context);
400             Assert.fail("IllegalArgumentException expected");
401         } catch (final IllegalArgumentException ex) {
402         }
403         try {
404             authStrategy.authFailed(authhost, authScheme, null);
405             Assert.fail("IllegalArgumentException expected");
406         } catch (final IllegalArgumentException ex) {
407         }
408     }
409 
410     @Test
411     public void testAuthFailed() throws Exception {
412         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
413         final HttpHost authhost = new HttpHost("somehost", 80);
414         final BasicScheme authScheme = new BasicScheme();
415         authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test"));
416 
417         final AuthCache authCache = Mockito.mock(AuthCache.class);
418 
419         final HttpClientContext context = HttpClientContext.create();
420         context.setAuthCache(authCache);
421 
422         authStrategy.authFailed(authhost, authScheme, context);
423         Mockito.verify(authCache).remove(authhost);
424     }
425 
426     @Test
427     public void testAuthFailedNoCache() throws Exception {
428         final TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
429         final HttpHost authhost = new HttpHost("somehost", 80);
430         final BasicScheme authScheme = new BasicScheme();
431 
432         final HttpClientContext context = HttpClientContext.create();
433         context.setAuthCache(null);
434 
435         authStrategy.authFailed(authhost, authScheme, context);
436     }
437 
438 }