From e7190e717756ffb71f20635bbe916b0dbcb23d1d Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Thu, 23 Jul 2015 10:00:13 +0000 Subject: [PATCH] Better separations of concerns: AuthenticationStrategy is intended to select preferred auth schemes without performing actual authentication; auth handling code moved to HttpAuthenticator git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1692370 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/http/auth/AuthScheme.java | 13 -- .../http/client/AuthenticationStrategy.java | 19 +- .../http/impl/auth/HttpAuthenticator.java | 162 +++++++++++------- .../client/DefaultAuthenticationStrategy.java | 36 +--- .../client/TestAuthenticationStrategy.java | 127 +++----------- .../integration/TestClientAuthentication.java | 14 +- .../impl/execchain/TestMainClientExec.java | 56 +++--- 7 files changed, 164 insertions(+), 263 deletions(-) diff --git a/httpclient/src/main/java/org/apache/http/auth/AuthScheme.java b/httpclient/src/main/java/org/apache/http/auth/AuthScheme.java index e888a88cc..e3fb57db8 100644 --- a/httpclient/src/main/java/org/apache/http/auth/AuthScheme.java +++ b/httpclient/src/main/java/org/apache/http/auth/AuthScheme.java @@ -34,19 +34,6 @@ import org.apache.http.protocol.HttpContext; * This interface represents an abstract challenge-response oriented * authentication scheme. *

- * An authentication scheme should be able to support the following - * functions: - *

- *

* Authentication schemes may be stateful involving a series of * challenge-response exchanges. * diff --git a/httpclient/src/main/java/org/apache/http/client/AuthenticationStrategy.java b/httpclient/src/main/java/org/apache/http/client/AuthenticationStrategy.java index 4fe700c74..5463c050d 100644 --- a/httpclient/src/main/java/org/apache/http/client/AuthenticationStrategy.java +++ b/httpclient/src/main/java/org/apache/http/client/AuthenticationStrategy.java @@ -27,14 +27,12 @@ package org.apache.http.client; +import java.util.List; import java.util.Map; -import java.util.Queue; -import org.apache.http.HttpHost; import org.apache.http.auth.AuthChallenge; -import org.apache.http.auth.AuthOption; +import org.apache.http.auth.AuthScheme; import org.apache.http.auth.ChallengeType; -import org.apache.http.auth.MalformedChallengeException; import org.apache.http.protocol.HttpContext; /** @@ -49,24 +47,19 @@ import org.apache.http.protocol.HttpContext; public interface AuthenticationStrategy { /** - * Selects one authentication challenge out of all available and - * creates and generates {@link AuthOption} instance capable of - * processing that challenge. + * Returns an list of {@link AuthScheme}s to handle the given {@link AuthChallenge}s + * in their order of preference. * * @param challengeType challenge type. - * @param host authentication host. * @param challenges collection of challenges. * @param context HTTP context. * @return authentication auth schemes that can be used for authentication. Can be empty. - * @throws MalformedChallengeException if one of the authentication - * challenges is not valid or malformed. * * @since 5.0 */ - Queue select( + List select( ChallengeType challengeType, - HttpHost host, Map challenges, - HttpContext context) throws MalformedChallengeException; + HttpContext context); } diff --git a/httpclient/src/main/java/org/apache/http/impl/auth/HttpAuthenticator.java b/httpclient/src/main/java/org/apache/http/impl/auth/HttpAuthenticator.java index 839fad110..5bda0666b 100644 --- a/httpclient/src/main/java/org/apache/http/impl/auth/HttpAuthenticator.java +++ b/httpclient/src/main/java/org/apache/http/impl/auth/HttpAuthenticator.java @@ -29,6 +29,7 @@ package org.apache.http.impl.auth; import java.io.IOException; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -49,10 +50,12 @@ import org.apache.http.auth.AuthChallenge; import org.apache.http.auth.AuthOption; import org.apache.http.auth.AuthProtocolState; import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthState; import org.apache.http.auth.AuthenticationException; import org.apache.http.auth.ChallengeType; import org.apache.http.auth.Credentials; +import org.apache.http.auth.CredentialsProvider; import org.apache.http.auth.MalformedChallengeException; import org.apache.http.client.AuthCache; import org.apache.http.client.AuthenticationStrategy; @@ -98,10 +101,13 @@ public class HttpAuthenticator { default: throw new IllegalStateException("Unexpected challenge type: " + challengeType); } + + final HttpClientContext clientContext = HttpClientContext.adapt(context); + if (response.getStatusLine().getStatusCode() == challengeCode) { this.log.debug("Authentication required"); if (authState.getState() == AuthProtocolState.SUCCESS) { - clearCache(host, context); + clearCache(host, clientContext); } return true; } else { @@ -110,7 +116,7 @@ public class HttpAuthenticator { case HANDSHAKE: this.log.debug("Authentication succeeded"); authState.setState(AuthProtocolState.SUCCESS); - updateCache(host, authState.getAuthScheme(), context); + updateCache(host, authState.getAuthScheme(), clientContext); break; case SUCCESS: break; @@ -132,51 +138,52 @@ public class HttpAuthenticator { if (this.log.isDebugEnabled()) { this.log.debug(host.toHostString() + " requested authentication"); } - try { - final Header[] headers = response.getHeaders( - challengeType == ChallengeType.PROXY ? HttpHeaders.PROXY_AUTHENTICATE : HttpHeaders.WWW_AUTHENTICATE); - final Map challengeMap = new HashMap<>(); - for (Header header: headers) { - final CharArrayBuffer buffer; - final int pos; - if (header instanceof FormattedHeader) { - buffer = ((FormattedHeader) header).getBuffer(); - pos = ((FormattedHeader) header).getValuePos(); - } else { - final String s = header.getValue(); - if (s == null) { - continue; - } - buffer = new CharArrayBuffer(s.length()); - buffer.append(s); - pos = 0; - } - final ParserCursor cursor = new ParserCursor(pos, buffer.length()); - final List authChallenges; - try { - authChallenges = parser.parse(buffer, cursor); - } catch (ParseException ex) { - if (this.log.isWarnEnabled()) { - this.log.warn("Malformed challenge: " + header.getValue()); - } + + final HttpClientContext clientContext = HttpClientContext.adapt(context); + + final Header[] headers = response.getHeaders( + challengeType == ChallengeType.PROXY ? HttpHeaders.PROXY_AUTHENTICATE : HttpHeaders.WWW_AUTHENTICATE); + final Map challengeMap = new HashMap<>(); + for (Header header: headers) { + final CharArrayBuffer buffer; + final int pos; + if (header instanceof FormattedHeader) { + buffer = ((FormattedHeader) header).getBuffer(); + pos = ((FormattedHeader) header).getValuePos(); + } else { + final String s = header.getValue(); + if (s == null) { continue; } - for (AuthChallenge authChallenge: authChallenges) { - final String scheme = authChallenge.getScheme().toLowerCase(Locale.ROOT); - if (!challengeMap.containsKey(scheme)) { - challengeMap.put(scheme, authChallenge); - } + buffer = new CharArrayBuffer(s.length()); + buffer.append(s); + pos = 0; + } + final ParserCursor cursor = new ParserCursor(pos, buffer.length()); + final List authChallenges; + try { + authChallenges = parser.parse(buffer, cursor); + } catch (ParseException ex) { + if (this.log.isWarnEnabled()) { + this.log.warn("Malformed challenge: " + header.getValue()); + } + continue; + } + for (AuthChallenge authChallenge: authChallenges) { + final String scheme = authChallenge.getScheme().toLowerCase(Locale.ROOT); + if (!challengeMap.containsKey(scheme)) { + challengeMap.put(scheme, authChallenge); } } - if (challengeMap.isEmpty()) { - this.log.debug("Response contains no valid authentication challenges"); - clearCache(host, context); - authState.reset(); - return false; - } + } + if (challengeMap.isEmpty()) { + this.log.debug("Response contains no valid authentication challenges"); + clearCache(host, clientContext); + authState.reset(); + return false; + } - final AuthScheme authScheme = authState.getAuthScheme(); - switch (authState.getState()) { + switch (authState.getState()) { case FAILURE: return false; case SUCCESS: @@ -184,17 +191,27 @@ public class HttpAuthenticator { break; case CHALLENGED: case HANDSHAKE: - Asserts.notNull(authScheme, "AuthScheme"); + Asserts.notNull(authState.getAuthScheme(), "AuthScheme"); case UNCHALLENGED: + final AuthScheme authScheme = authState.getAuthScheme(); if (authScheme != null) { final String id = authScheme.getSchemeName(); final AuthChallenge challenge = challengeMap.get(id.toLowerCase(Locale.ROOT)); if (challenge != null) { this.log.debug("Authorization challenge processed"); - authScheme.processChallenge(challengeType, challenge); + try { + authScheme.processChallenge(challengeType, challenge); + } catch (MalformedChallengeException ex) { + if (this.log.isWarnEnabled()) { + this.log.warn(ex.getMessage()); + } + clearCache(host, clientContext); + authState.reset(); + return false; + } if (authScheme.isComplete()) { this.log.debug("Authentication failed"); - clearCache(host, context); + clearCache(host, clientContext); authState.reset(); authState.setState(AuthProtocolState.FAILURE); return false; @@ -207,23 +224,44 @@ public class HttpAuthenticator { // Retry authentication with a different scheme } } - } - final Queue authOptions = authStrategy.select(challengeType, host, challengeMap, context); - if (authOptions != null && !authOptions.isEmpty()) { - if (this.log.isDebugEnabled()) { - this.log.debug("Selected authentication options: " + authOptions); + } + + final List preferredSchemes = authStrategy.select(challengeType, challengeMap, context); + final CredentialsProvider credsProvider = clientContext.getCredentialsProvider(); + if (credsProvider == null) { + this.log.debug("Credentials provider not set in the context"); + return false; + } + + final Queue authOptions = new LinkedList<>(); + for (AuthScheme authScheme: preferredSchemes) { + try { + final String id = authScheme.getSchemeName(); + final AuthChallenge challenge = challengeMap.get(id.toLowerCase(Locale.ROOT)); + authScheme.processChallenge(challengeType, challenge); + final AuthScope authScope = new AuthScope( + host.getHostName(), + host.getPort(), + authScheme.getRealm(), + authScheme.getSchemeName()); + final Credentials credentials = credsProvider.getCredentials(authScope); + if (credentials != null) { + authOptions.add(new AuthOption(authScheme, credentials)); + } + } catch (MalformedChallengeException ex) { + if (this.log.isWarnEnabled()) { + this.log.warn(ex.getMessage()); } - authState.setState(AuthProtocolState.CHALLENGED); - authState.update(authOptions); - return true; - } else { - return false; } - } catch (final MalformedChallengeException ex) { - if (this.log.isWarnEnabled()) { - this.log.warn("Malformed challenge: " + ex.getMessage()); + } + if (!authOptions.isEmpty()) { + if (this.log.isDebugEnabled()) { + this.log.debug("Selected authentication options: " + authOptions); } - authState.reset(); + authState.setState(AuthProtocolState.CHALLENGED); + authState.update(authOptions); + return true; + } else { return false; } } @@ -292,9 +330,8 @@ public class HttpAuthenticator { schemeName.equalsIgnoreCase(AuthSchemes.DIGEST); } - private void updateCache(final HttpHost host, final AuthScheme authScheme, final HttpContext context) { + private void updateCache(final HttpHost host, final AuthScheme authScheme, final HttpClientContext clientContext) { if (isCachable(authScheme)) { - final HttpClientContext clientContext = HttpClientContext.adapt(context); final AuthCache authCache = clientContext.getAuthCache(); if (authCache != null) { if (this.log.isDebugEnabled()) { @@ -305,9 +342,8 @@ public class HttpAuthenticator { } } - private void clearCache(final HttpHost host, final HttpContext context) { + private void clearCache(final HttpHost host, final HttpClientContext clientContext) { - final HttpClientContext clientContext = HttpClientContext.adapt(context); final AuthCache authCache = clientContext.getAuthCache(); if (authCache != null) { if (this.log.isDebugEnabled()) { diff --git a/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java b/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java index 70922b41f..eb5b9d753 100644 --- a/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java +++ b/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java @@ -27,28 +27,21 @@ package org.apache.http.impl.client; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Queue; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.http.HttpHost; import org.apache.http.annotation.Immutable; import org.apache.http.auth.AuthChallenge; -import org.apache.http.auth.AuthOption; import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeProvider; -import org.apache.http.auth.AuthScope; import org.apache.http.auth.ChallengeType; -import org.apache.http.auth.Credentials; -import org.apache.http.auth.CredentialsProvider; -import org.apache.http.auth.MalformedChallengeException; import org.apache.http.client.AuthenticationStrategy; import org.apache.http.client.config.AuthSchemes; import org.apache.http.client.config.RequestConfig; @@ -78,28 +71,21 @@ public class DefaultAuthenticationStrategy implements AuthenticationStrategy { AuthSchemes.BASIC)); @Override - public Queue select( + public List select( final ChallengeType challengeType, - final HttpHost authhost, final Map challenges, - final HttpContext context) throws MalformedChallengeException { + final HttpContext context) { Args.notNull(challengeType, "ChallengeType"); Args.notNull(challenges, "Map of auth challenges"); - Args.notNull(authhost, "Host"); Args.notNull(context, "HTTP context"); final HttpClientContext clientContext = HttpClientContext.adapt(context); - final Queue options = new LinkedList<>(); + final List options = new ArrayList<>(); final Lookup registry = clientContext.getAuthSchemeRegistry(); if (registry == null) { this.log.debug("Auth scheme registry not set in the context"); return options; } - final CredentialsProvider credsProvider = clientContext.getCredentialsProvider(); - if (credsProvider == null) { - this.log.debug("Credentials provider not set in the context"); - return options; - } final RequestConfig config = clientContext.getRequestConfig(); Collection authPrefs = challengeType == ChallengeType.TARGET ? config.getTargetPreferredAuthSchemes() : config.getProxyPreferredAuthSchemes(); @@ -122,22 +108,10 @@ public class DefaultAuthenticationStrategy implements AuthenticationStrategy { continue; } final AuthScheme authScheme = authSchemeProvider.create(context); - authScheme.processChallenge(challengeType, challenge); - - final AuthScope authScope = new AuthScope( - authhost.getHostName(), - authhost.getPort(), - authScheme.getRealm(), - authScheme.getSchemeName()); - - final Credentials credentials = credsProvider.getCredentials(authScope); - if (credentials != null) { - options.add(new AuthOption(authScheme, credentials)); - } + options.add(authScheme); } else { if (this.log.isDebugEnabled()) { this.log.debug("Challenge for " + id + " authentication scheme not available"); - // Try again } } } diff --git a/httpclient/src/test/java/org/apache/http/impl/client/TestAuthenticationStrategy.java b/httpclient/src/test/java/org/apache/http/impl/client/TestAuthenticationStrategy.java index 517844bdc..58268c8dd 100644 --- a/httpclient/src/test/java/org/apache/http/impl/client/TestAuthenticationStrategy.java +++ b/httpclient/src/test/java/org/apache/http/impl/client/TestAuthenticationStrategy.java @@ -29,16 +29,14 @@ package org.apache.http.impl.client; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; -import java.util.Queue; -import org.apache.http.HttpHost; import org.apache.http.auth.AuthChallenge; -import org.apache.http.auth.AuthOption; +import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthSchemeProvider; import org.apache.http.auth.AuthScope; import org.apache.http.auth.ChallengeType; -import org.apache.http.auth.CredentialsProvider; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.config.AuthSchemes; import org.apache.http.client.config.RequestConfig; @@ -62,25 +60,19 @@ public class TestAuthenticationStrategy { @Test public void testSelectInvalidInput() throws Exception { final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy(); - final HttpHost authhost = new HttpHost("locahost", 80); final HttpClientContext context = HttpClientContext.create(); try { - authStrategy.select(null, authhost, Collections.emptyMap(), context); + authStrategy.select(null, Collections.emptyMap(), context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } try { - authStrategy.select(ChallengeType.TARGET, null, Collections.emptyMap(), context); + authStrategy.select(ChallengeType.TARGET, null, context); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } try { - authStrategy.select(ChallengeType.TARGET, authhost, null, context); - Assert.fail("IllegalArgumentException expected"); - } catch (final IllegalArgumentException ex) { - } - try { - authStrategy.select(ChallengeType.TARGET, authhost, Collections.emptyMap(), null); + authStrategy.select(ChallengeType.TARGET, Collections.emptyMap(), null); Assert.fail("IllegalArgumentException expected"); } catch (final IllegalArgumentException ex) { } @@ -89,7 +81,6 @@ public class TestAuthenticationStrategy { @Test public void testSelectNoSchemeRegistry() throws Exception { final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy(); - final HttpHost authhost = new HttpHost("locahost", 80); final HttpClientContext context = HttpClientContext.create(); final Map challenges = new HashMap<>(); @@ -98,91 +89,14 @@ public class TestAuthenticationStrategy { challenges.put("digest", new AuthChallenge("Digest", new BasicNameValuePair("realm", "test"), new BasicNameValuePair("nonce", "1234"))); - final Queue options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context); - Assert.assertNotNull(options); - Assert.assertEquals(0, options.size()); - } - - @Test - public void testSelectNoCredentialsProvider() throws Exception { - final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy(); - final HttpHost authhost = new HttpHost("locahost", 80); - final HttpClientContext context = HttpClientContext.create(); - - final Map challenges = new HashMap<>(); - challenges.put("basic", new AuthChallenge("Basic", - new BasicNameValuePair("realm", "test"))); - challenges.put("digest", new AuthChallenge("Digest", - new BasicNameValuePair("realm", "test"), new BasicNameValuePair("nonce", "1234"))); - - final Registry authSchemeRegistry = RegistryBuilder.create() - .register("basic", new BasicSchemeFactory()) - .register("digest", new DigestSchemeFactory()).build(); - context.setAuthSchemeRegistry(authSchemeRegistry); - - final Queue options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context); - Assert.assertNotNull(options); - Assert.assertEquals(0, options.size()); - } - - @Test - public void testNoCredentials() throws Exception { - final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy(); - final HttpHost authhost = new HttpHost("locahost", 80); - final HttpClientContext context = HttpClientContext.create(); - - final Map challenges = new HashMap<>(); - challenges.put("basic", new AuthChallenge("Basic", - new BasicNameValuePair("realm", "realm1"))); - challenges.put("digest", new AuthChallenge("Digest", - new BasicNameValuePair("realm", "realm2"), new BasicNameValuePair("nonce", "1234"))); - - final Registry authSchemeRegistry = RegistryBuilder.create() - .register("basic", new BasicSchemeFactory()) - .register("digest", new DigestSchemeFactory()).build(); - context.setAuthSchemeRegistry(authSchemeRegistry); - - final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); - context.setCredentialsProvider(credentialsProvider); - - final Queue options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context); - Assert.assertNotNull(options); - Assert.assertEquals(0, options.size()); - } - - @Test - public void testCredentialsFound() throws Exception { - final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy(); - final HttpHost authhost = new HttpHost("somehost", 80); - final HttpClientContext context = HttpClientContext.create(); - - final Map challenges = new HashMap<>(); - challenges.put("basic", new AuthChallenge("Basic", - new BasicNameValuePair("realm", "realm1"))); - challenges.put("digest", new AuthChallenge("Digest", - new BasicNameValuePair("realm", "realm2"), new BasicNameValuePair("nonce", "1234"))); - - final Registry authSchemeRegistry = RegistryBuilder.create() - .register("basic", new BasicSchemeFactory()) - .register("digest", new DigestSchemeFactory()).build(); - context.setAuthSchemeRegistry(authSchemeRegistry); - - final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); - credentialsProvider.setCredentials(new AuthScope("somehost", 80, "realm2"), - new UsernamePasswordCredentials("user", "pwd")); - context.setCredentialsProvider(credentialsProvider); - - final Queue options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context); - Assert.assertNotNull(options); - Assert.assertEquals(1, options.size()); - final AuthOption option = options.remove(); - Assert.assertTrue(option.getAuthScheme() instanceof DigestScheme); + final List authSchemes = authStrategy.select(ChallengeType.TARGET, challenges, context); + Assert.assertNotNull(authSchemes); + Assert.assertEquals(0, authSchemes.size()); } @Test public void testUnsupportedScheme() throws Exception { final DefaultAuthenticationStrategy authStrategy = new DefaultAuthenticationStrategy(); - final HttpHost authhost = new HttpHost("somehost", 80); final HttpClientContext context = HttpClientContext.create(); final Map challenges = new HashMap<>(); @@ -203,13 +117,13 @@ public class TestAuthenticationStrategy { new UsernamePasswordCredentials("user", "pwd")); context.setCredentialsProvider(credentialsProvider); - final Queue options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context); - Assert.assertNotNull(options); - Assert.assertEquals(2, options.size()); - final AuthOption option1 = options.remove(); - Assert.assertTrue(option1.getAuthScheme() instanceof DigestScheme); - final AuthOption option2 = options.remove(); - Assert.assertTrue(option2.getAuthScheme() instanceof BasicScheme); + final List authSchemes = authStrategy.select(ChallengeType.TARGET, challenges, context); + Assert.assertNotNull(authSchemes); + Assert.assertEquals(2, authSchemes.size()); + final AuthScheme authScheme1 = authSchemes.get(0); + Assert.assertTrue(authScheme1 instanceof DigestScheme); + final AuthScheme authScheme2 = authSchemes.get(1); + Assert.assertTrue(authScheme2 instanceof BasicScheme); } @Test @@ -219,7 +133,6 @@ public class TestAuthenticationStrategy { .setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)) .build(); - final HttpHost authhost = new HttpHost("somehost", 80); final HttpClientContext context = HttpClientContext.create(); final Map challenges = new HashMap<>(); @@ -239,11 +152,11 @@ public class TestAuthenticationStrategy { new UsernamePasswordCredentials("user", "pwd")); context.setCredentialsProvider(credentialsProvider); - final Queue options = authStrategy.select(ChallengeType.TARGET, authhost, challenges, context); - Assert.assertNotNull(options); - Assert.assertEquals(1, options.size()); - final AuthOption option1 = options.remove(); - Assert.assertTrue(option1.getAuthScheme() instanceof BasicScheme); + final List authSchemes = authStrategy.select(ChallengeType.TARGET, challenges, context); + Assert.assertNotNull(authSchemes); + Assert.assertEquals(1, authSchemes.size()); + final AuthScheme authScheme1 = authSchemes.get(0); + Assert.assertTrue(authScheme1 instanceof BasicScheme); } } diff --git a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthentication.java b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthentication.java index 7663f6eac..f134b223c 100644 --- a/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthentication.java +++ b/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthentication.java @@ -28,8 +28,8 @@ package org.apache.http.impl.client.integration; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.util.List; import java.util.Map; -import java.util.Queue; import java.util.concurrent.atomic.AtomicLong; import org.apache.http.Consts; @@ -42,12 +42,11 @@ import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.auth.AuthChallenge; -import org.apache.http.auth.AuthOption; +import org.apache.http.auth.AuthScheme; import org.apache.http.auth.AuthScope; import org.apache.http.auth.ChallengeType; import org.apache.http.auth.Credentials; import org.apache.http.auth.CredentialsProvider; -import org.apache.http.auth.MalformedChallengeException; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.AuthCache; import org.apache.http.client.ClientProtocolException; @@ -358,14 +357,13 @@ public class TestClientAuthentication extends LocalServerTestBase { } @Override - public Queue select( + public List select( final ChallengeType challengeType, - final HttpHost host, final Map challenges, - final HttpContext context) throws MalformedChallengeException { - final Queue authOptions = super.select(challengeType, host, challenges, context); + final HttpContext context) { + final List authSchemes = super.select(challengeType, challenges, context); this.count.incrementAndGet(); - return authOptions; + return authSchemes; } public long getCount() { diff --git a/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientExec.java b/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientExec.java index 3c839d178..04ac73208 100644 --- a/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientExec.java +++ b/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientExec.java @@ -31,9 +31,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; -import java.util.Arrays; import java.util.Collections; -import java.util.LinkedList; import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -48,8 +46,9 @@ import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.auth.AuthChallenge; -import org.apache.http.auth.AuthOption; import org.apache.http.auth.AuthProtocolState; +import org.apache.http.auth.AuthScheme; +import org.apache.http.auth.AuthScope; import org.apache.http.auth.AuthState; import org.apache.http.auth.ChallengeType; import org.apache.http.auth.NTCredentials; @@ -74,6 +73,7 @@ import org.apache.http.conn.routing.RouteInfo; import org.apache.http.entity.StringEntity; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.impl.auth.NTLMScheme; +import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.conn.ConnectionShutdownException; import org.apache.http.message.BasicHttpResponse; import org.apache.http.protocol.HttpContext; @@ -396,6 +396,10 @@ public class TestMainClientExec { .setStream(instream2) .build()); + final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(new AuthScope(target), new UsernamePasswordCredentials("user:pass")); + context.setCredentialsProvider(credentialsProvider); + Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( @@ -407,12 +411,8 @@ public class TestMainClientExec { Mockito.any())).thenReturn(Boolean.TRUE); Mockito.when(targetAuthStrategy.select( Mockito.eq(ChallengeType.TARGET), - Mockito.eq(target), Mockito.>any(), - Mockito.any())).thenReturn(new LinkedList<>( - Collections.singleton(new AuthOption( - new BasicScheme(), - new UsernamePasswordCredentials("user", "pass"))))); + Mockito.any())).thenReturn(Collections.singletonList(new BasicScheme())); final CloseableHttpResponse finalResponse = mainClientExec.execute( route, request, context, execAware); @@ -447,6 +447,10 @@ public class TestMainClientExec { final HttpClientContext context = new HttpClientContext(); context.setAttribute(HttpClientContext.PROXY_AUTH_STATE, proxyAuthState); + final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(new AuthScope(target), new UsernamePasswordCredentials("user:pass")); + context.setCredentialsProvider(credentialsProvider); + Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( @@ -457,14 +461,10 @@ public class TestMainClientExec { Mockito.any(), Mockito.any())).thenReturn(Boolean.FALSE); - final AuthOption authOption = new AuthOption( - new BasicScheme(), new UsernamePasswordCredentials("user:pass")); Mockito.when(targetAuthStrategy.select( Mockito.eq(ChallengeType.TARGET), - Mockito.eq(target), Mockito.>any(), - Mockito.any())).thenReturn( - new LinkedList<>(Arrays.asList(authOption))); + Mockito.any())).thenReturn(Collections.singletonList(new BasicScheme())); final CloseableHttpResponse finalResponse = mainClientExec.execute( route, request, context, execAware); @@ -496,6 +496,10 @@ public class TestMainClientExec { .setStream(instream1) .build()); + final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(new AuthScope(target), new UsernamePasswordCredentials("user:pass")); + context.setCredentialsProvider(credentialsProvider); + Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(managedConn.isStale()).thenReturn(Boolean.FALSE); Mockito.when(requestExecutor.execute( @@ -516,14 +520,10 @@ public class TestMainClientExec { Mockito.any(), Mockito.any())).thenReturn(Boolean.TRUE); - final AuthOption authOption = new AuthOption( - new BasicScheme(), new UsernamePasswordCredentials("user:pass")); Mockito.when(targetAuthStrategy.select( Mockito.eq(ChallengeType.TARGET), - Mockito.eq(target), Mockito.>any(), - Mockito.any())).thenReturn( - new LinkedList<>(Arrays.asList(authOption))); + Mockito.any())).thenReturn(Collections.singletonList(new BasicScheme())); mainClientExec.execute(route, request, context, execAware); } @@ -724,6 +724,10 @@ public class TestMainClientExec { .build()); final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(new AuthScope(proxy), new UsernamePasswordCredentials("user:pass")); + context.setCredentialsProvider(credentialsProvider); + Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(reuseStrategy.keepAlive( Mockito.any(), @@ -733,14 +737,10 @@ public class TestMainClientExec { Mockito.any(), Mockito.any())).thenReturn(response1, response2); - final AuthOption authOption = new AuthOption( - new BasicScheme(), new UsernamePasswordCredentials("user:pass")); Mockito.when(proxyAuthStrategy.select( Mockito.eq(ChallengeType.PROXY), - Mockito.eq(proxy), Mockito.>any(), - Mockito.any())).thenReturn( - new LinkedList<>(Arrays.asList(authOption))); + Mockito.any())).thenReturn(Collections.singletonList(new BasicScheme())); mainClientExec.establishRoute(authState, managedConn, route, request, context); @@ -763,6 +763,10 @@ public class TestMainClientExec { .build()); final HttpResponse response2 = new BasicHttpResponse(HttpVersion.HTTP_1_1, 200, "OK"); + final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider(); + credentialsProvider.setCredentials(new AuthScope(proxy), new UsernamePasswordCredentials("user:pass")); + context.setCredentialsProvider(credentialsProvider); + Mockito.when(managedConn.isOpen()).thenReturn(Boolean.TRUE); Mockito.when(reuseStrategy.keepAlive( Mockito.any(), @@ -772,14 +776,10 @@ public class TestMainClientExec { Mockito.any(), Mockito.any())).thenReturn(response1, response2); - final AuthOption authOption = new AuthOption( - new BasicScheme(), new UsernamePasswordCredentials("user:pass")); Mockito.when(proxyAuthStrategy.select( Mockito.eq(ChallengeType.PROXY), - Mockito.eq(proxy), Mockito.>any(), - Mockito.any())).thenReturn( - new LinkedList<>(Arrays.asList(authOption))); + Mockito.any())).thenReturn(Collections.singletonList(new BasicScheme())); mainClientExec.establishRoute(authState, managedConn, route, request, context);