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
This commit is contained in:
Oleg Kalnichevski 2015-07-23 10:00:13 +00:00
parent b2a7cb9f10
commit e7190e7177
7 changed files with 164 additions and 263 deletions

View File

@ -34,19 +34,6 @@ import org.apache.http.protocol.HttpContext;
* This interface represents an abstract challenge-response oriented
* authentication scheme.
* <p>
* An authentication scheme should be able to support the following
* functions:
* <ul>
* <li>Parse and process the challenge sent by the target server
* in response to request for a protected resource
* <li>Provide its textual designation
* <li>Provide its parameters, if available
* <li>Provide the realm this authentication scheme is applicable to,
* if available
* <li>Generate authorization string for the given set of credentials
* and the HTTP request in response to the authorization challenge.
* </ul>
* <p>
* Authentication schemes may be stateful involving a series of
* challenge-response exchanges.
*

View File

@ -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<AuthOption> select(
List<AuthScheme> select(
ChallengeType challengeType,
HttpHost host,
Map<String, AuthChallenge> challenges,
HttpContext context) throws MalformedChallengeException;
HttpContext context);
}

View File

@ -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<String, AuthChallenge> 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<AuthChallenge> 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<String, AuthChallenge> 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<AuthChallenge> 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<AuthOption> 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<AuthScheme> 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<AuthOption> 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()) {

View File

@ -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<AuthOption> select(
public List<AuthScheme> select(
final ChallengeType challengeType,
final HttpHost authhost,
final Map<String, AuthChallenge> 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<AuthOption> options = new LinkedList<>();
final List<AuthScheme> options = new ArrayList<>();
final Lookup<AuthSchemeProvider> 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<String> 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
}
}
}

View File

@ -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.<String, AuthChallenge>emptyMap(), context);
authStrategy.select(null, Collections.<String, AuthChallenge>emptyMap(), context);
Assert.fail("IllegalArgumentException expected");
} catch (final IllegalArgumentException ex) {
}
try {
authStrategy.select(ChallengeType.TARGET, null, Collections.<String, AuthChallenge>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.<String, AuthChallenge>emptyMap(), null);
authStrategy.select(ChallengeType.TARGET, Collections.<String, AuthChallenge>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<String, AuthChallenge> 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<AuthOption> 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<String, AuthChallenge> 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<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
.register("basic", new BasicSchemeFactory())
.register("digest", new DigestSchemeFactory()).build();
context.setAuthSchemeRegistry(authSchemeRegistry);
final Queue<AuthOption> 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<String, AuthChallenge> 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<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
.register("basic", new BasicSchemeFactory())
.register("digest", new DigestSchemeFactory()).build();
context.setAuthSchemeRegistry(authSchemeRegistry);
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
context.setCredentialsProvider(credentialsProvider);
final Queue<AuthOption> 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<String, AuthChallenge> 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<AuthSchemeProvider> authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>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<AuthOption> 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<AuthScheme> 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<String, AuthChallenge> challenges = new HashMap<>();
@ -203,13 +117,13 @@ public class TestAuthenticationStrategy {
new UsernamePasswordCredentials("user", "pwd"));
context.setCredentialsProvider(credentialsProvider);
final Queue<AuthOption> 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<AuthScheme> 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<String, AuthChallenge> challenges = new HashMap<>();
@ -239,11 +152,11 @@ public class TestAuthenticationStrategy {
new UsernamePasswordCredentials("user", "pwd"));
context.setCredentialsProvider(credentialsProvider);
final Queue<AuthOption> 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<AuthScheme> 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);
}
}

View File

@ -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<AuthOption> select(
public List<AuthScheme> select(
final ChallengeType challengeType,
final HttpHost host,
final Map<String, AuthChallenge> challenges,
final HttpContext context) throws MalformedChallengeException {
final Queue<AuthOption> authOptions = super.select(challengeType, host, challenges, context);
final HttpContext context) {
final List<AuthScheme> authSchemes = super.select(challengeType, challenges, context);
this.count.incrementAndGet();
return authOptions;
return authSchemes;
}
public long getCount() {

View File

@ -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.<HttpClientContext>any())).thenReturn(Boolean.TRUE);
Mockito.when(targetAuthStrategy.select(
Mockito.eq(ChallengeType.TARGET),
Mockito.eq(target),
Mockito.<Map<String, AuthChallenge>>any(),
Mockito.<HttpClientContext>any())).thenReturn(new LinkedList<>(
Collections.singleton(new AuthOption(
new BasicScheme(),
new UsernamePasswordCredentials("user", "pass")))));
Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>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.<HttpResponse>any(),
Mockito.<HttpClientContext>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.<Map<String, AuthChallenge>>any(),
Mockito.<HttpClientContext>any())).thenReturn(
new LinkedList<>(Arrays.asList(authOption)));
Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>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.<HttpResponse>any(),
Mockito.<HttpClientContext>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.<Map<String, AuthChallenge>>any(),
Mockito.<HttpClientContext>any())).thenReturn(
new LinkedList<>(Arrays.asList(authOption)));
Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>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.<HttpResponse>any(),
@ -733,14 +737,10 @@ public class TestMainClientExec {
Mockito.<HttpClientConnection>any(),
Mockito.<HttpClientContext>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.<Map<String, AuthChallenge>>any(),
Mockito.<HttpClientContext>any())).thenReturn(
new LinkedList<>(Arrays.asList(authOption)));
Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>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.<HttpResponse>any(),
@ -772,14 +776,10 @@ public class TestMainClientExec {
Mockito.<HttpClientConnection>any(),
Mockito.<HttpClientContext>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.<Map<String, AuthChallenge>>any(),
Mockito.<HttpClientContext>any())).thenReturn(
new LinkedList<>(Arrays.asList(authOption)));
Mockito.<HttpClientContext>any())).thenReturn(Collections.<AuthScheme>singletonList(new BasicScheme()));
mainClientExec.establishRoute(authState, managedConn, route, request, context);