Redesigned auth caching
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1182515 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4d1b157272
commit
732095943f
|
@ -34,6 +34,7 @@ import org.apache.http.Header;
|
|||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.auth.AuthOption;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
|
||||
|
@ -52,13 +53,16 @@ public interface AuthenticationStrategy {
|
|||
/**
|
||||
* Determines if the given HTTP response response represents
|
||||
* an authentication challenge that was sent back as a result
|
||||
* of authentication failure
|
||||
* of authentication failure.
|
||||
*
|
||||
* @param authhost authentication host.
|
||||
* @param response HTTP response.
|
||||
* @param context HTTP context.
|
||||
* @return <code>true</code> if user authentication is required,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
boolean isAuthenticationRequested(
|
||||
HttpHost authhost,
|
||||
HttpResponse response,
|
||||
HttpContext context);
|
||||
|
||||
|
@ -67,6 +71,7 @@ public interface AuthenticationStrategy {
|
|||
* challenges, each of which represents an authentication scheme supported
|
||||
* by the authentication host.
|
||||
*
|
||||
* @param authhost authentication host.
|
||||
* @param response HTTP response.
|
||||
* @param context HTTP context.
|
||||
* @return a collection of challenges keyed by names of corresponding
|
||||
|
@ -75,6 +80,7 @@ public interface AuthenticationStrategy {
|
|||
* challenges is not valid or malformed.
|
||||
*/
|
||||
Map<String, Header> getChallenges(
|
||||
HttpHost authhost,
|
||||
HttpResponse response,
|
||||
HttpContext context) throws MalformedChallengeException;
|
||||
|
||||
|
@ -82,7 +88,9 @@ public interface AuthenticationStrategy {
|
|||
* Selects one authentication challenge out of all available and
|
||||
* creates and generates {@link AuthOption} instance capable of
|
||||
* processing that challenge.
|
||||
*
|
||||
* @param challenges collection of challenges.
|
||||
* @param authhost authentication host.
|
||||
* @param response HTTP response.
|
||||
* @param context HTTP context.
|
||||
* @return authentication auth schemes that can be used for authentication. Can be empty.
|
||||
|
@ -95,4 +103,28 @@ public interface AuthenticationStrategy {
|
|||
HttpResponse response,
|
||||
HttpContext context) throws MalformedChallengeException;
|
||||
|
||||
/**
|
||||
* Callback invoked in case of successful authentication.
|
||||
*
|
||||
* @param authhost authentication host.
|
||||
* @param authScheme authentication scheme used.
|
||||
* @param context HTTP context.
|
||||
*/
|
||||
void authSucceeded(
|
||||
HttpHost authhost,
|
||||
AuthScheme authScheme,
|
||||
HttpContext context);
|
||||
|
||||
/**
|
||||
* Callback invoked in case of unsuccessful authentication.
|
||||
*
|
||||
* @param authhost authentication host.
|
||||
* @param authScheme authentication scheme used.
|
||||
* @param context HTTP context.
|
||||
*/
|
||||
void authFailed(
|
||||
HttpHost authhost,
|
||||
AuthScheme authScheme,
|
||||
HttpContext context);
|
||||
|
||||
}
|
||||
|
|
|
@ -127,6 +127,7 @@ public class RequestAuthCache implements HttpRequestInterceptor {
|
|||
Credentials creds = credsProvider.getCredentials(authScope);
|
||||
|
||||
if (creds != null) {
|
||||
authState.setState(AuthProtocolState.SUCCESS);
|
||||
authState.update(authScheme, creds);
|
||||
} else {
|
||||
this.log.debug("No credentials for preemptive authentication");
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.apache.http.annotation.Immutable;
|
|||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.AuthState;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.AuthenticationStrategy;
|
||||
import org.apache.http.client.params.AuthPolicy;
|
||||
import org.apache.http.conn.scheme.Scheme;
|
||||
import org.apache.http.conn.scheme.SchemeRegistry;
|
||||
|
@ -53,8 +54,11 @@ import org.apache.http.protocol.HttpContext;
|
|||
* additional authentication round-trips.
|
||||
*
|
||||
* @since 4.1
|
||||
*
|
||||
* @deprecated use {@link AuthenticationStrategy}
|
||||
*/
|
||||
@Immutable
|
||||
@Deprecated
|
||||
public class ResponseAuthCache implements HttpResponseInterceptor {
|
||||
|
||||
private final Log log = LogFactory.getLog(getClass());
|
||||
|
|
|
@ -44,9 +44,11 @@ import org.apache.http.auth.AuthScope;
|
|||
import org.apache.http.auth.AuthenticationException;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.AuthenticationHandler;
|
||||
import org.apache.http.client.AuthenticationStrategy;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.client.params.AuthPolicy;
|
||||
import org.apache.http.client.protocol.ClientContext;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
|
||||
|
@ -68,11 +70,15 @@ class AuthenticationStrategyAdaptor implements AuthenticationStrategy {
|
|||
this.handler = handler;
|
||||
}
|
||||
|
||||
public boolean isAuthenticationRequested(final HttpResponse response, final HttpContext context) {
|
||||
public boolean isAuthenticationRequested(
|
||||
final HttpHost authhost,
|
||||
final HttpResponse response,
|
||||
final HttpContext context) {
|
||||
return this.handler.isAuthenticationRequested(response, context);
|
||||
}
|
||||
|
||||
public Map<String, Header> getChallenges(
|
||||
final HttpHost authhost,
|
||||
final HttpResponse response,
|
||||
final HttpContext context) throws MalformedChallengeException {
|
||||
return this.handler.getChallenges(response, context);
|
||||
|
@ -130,6 +136,44 @@ class AuthenticationStrategyAdaptor implements AuthenticationStrategy {
|
|||
return options;
|
||||
}
|
||||
|
||||
public void authSucceeded(
|
||||
final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) {
|
||||
AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE);
|
||||
if (isCachable(authScheme)) {
|
||||
if (authCache == null) {
|
||||
authCache = new BasicAuthCache();
|
||||
context.setAttribute(ClientContext.AUTH_CACHE, authCache);
|
||||
}
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Caching '" + authScheme.getSchemeName() +
|
||||
"' auth scheme for " + authhost);
|
||||
}
|
||||
authCache.put(authhost, authScheme);
|
||||
}
|
||||
}
|
||||
|
||||
public void authFailed(
|
||||
final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) {
|
||||
AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE);
|
||||
if (authCache == null) {
|
||||
return;
|
||||
}
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Removing from cache '" + authScheme.getSchemeName() +
|
||||
"' auth scheme for " + authhost);
|
||||
}
|
||||
authCache.remove(authhost);
|
||||
}
|
||||
|
||||
private boolean isCachable(final AuthScheme authScheme) {
|
||||
if (authScheme == null || !authScheme.isComplete()) {
|
||||
return false;
|
||||
}
|
||||
String schemeName = authScheme.getSchemeName();
|
||||
return schemeName.equalsIgnoreCase(AuthPolicy.BASIC) ||
|
||||
schemeName.equalsIgnoreCase(AuthPolicy.DIGEST);
|
||||
}
|
||||
|
||||
public AuthenticationHandler getHandler() {
|
||||
return this.handler;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ import org.apache.http.auth.AuthSchemeRegistry;
|
|||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.AuthenticationStrategy;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.client.params.AuthPolicy;
|
||||
|
@ -81,7 +82,10 @@ class AuthenticationStrategyImpl implements AuthenticationStrategy {
|
|||
this.prefParamName = prefParamName;
|
||||
}
|
||||
|
||||
public boolean isAuthenticationRequested(final HttpResponse response, final HttpContext context) {
|
||||
public boolean isAuthenticationRequested(
|
||||
final HttpHost authhost,
|
||||
final HttpResponse response,
|
||||
final HttpContext context) {
|
||||
if (response == null) {
|
||||
throw new IllegalArgumentException("HTTP response may not be null");
|
||||
}
|
||||
|
@ -90,6 +94,7 @@ class AuthenticationStrategyImpl implements AuthenticationStrategy {
|
|||
}
|
||||
|
||||
public Map<String, Header> getChallenges(
|
||||
final HttpHost authhost,
|
||||
final HttpResponse response,
|
||||
final HttpContext context) throws MalformedChallengeException {
|
||||
if (response == null) {
|
||||
|
@ -200,4 +205,59 @@ class AuthenticationStrategyImpl implements AuthenticationStrategy {
|
|||
return options;
|
||||
}
|
||||
|
||||
public void authSucceeded(
|
||||
final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) {
|
||||
if (authhost == null) {
|
||||
throw new IllegalArgumentException("Host may not be null");
|
||||
}
|
||||
if (authScheme == null) {
|
||||
throw new IllegalArgumentException("Auth scheme may not be null");
|
||||
}
|
||||
if (context == null) {
|
||||
throw new IllegalArgumentException("HTTP context may not be null");
|
||||
}
|
||||
if (isCachable(authScheme)) {
|
||||
AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE);
|
||||
if (authCache == null) {
|
||||
authCache = new BasicAuthCache();
|
||||
context.setAttribute(ClientContext.AUTH_CACHE, authCache);
|
||||
}
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Caching '" + authScheme.getSchemeName() +
|
||||
"' auth scheme for " + authhost);
|
||||
}
|
||||
authCache.put(authhost, authScheme);
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isCachable(final AuthScheme authScheme) {
|
||||
if (authScheme == null || !authScheme.isComplete()) {
|
||||
return false;
|
||||
}
|
||||
String schemeName = authScheme.getSchemeName();
|
||||
return schemeName.equalsIgnoreCase(AuthPolicy.BASIC) ||
|
||||
schemeName.equalsIgnoreCase(AuthPolicy.DIGEST);
|
||||
}
|
||||
|
||||
public void authFailed(
|
||||
final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) {
|
||||
if (authhost == null) {
|
||||
throw new IllegalArgumentException("Host may not be null");
|
||||
}
|
||||
if (authScheme == null) {
|
||||
throw new IllegalArgumentException("Auth scheme may not be null");
|
||||
}
|
||||
if (context == null) {
|
||||
throw new IllegalArgumentException("HTTP context may not be null");
|
||||
}
|
||||
AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE);
|
||||
if (authCache != null) {
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Removing from cache '" + authScheme.getSchemeName() +
|
||||
"' auth scheme for " + authhost);
|
||||
}
|
||||
authCache.remove(authhost);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ import org.apache.http.client.protocol.RequestClientConnControl;
|
|||
import org.apache.http.client.protocol.RequestDefaultHeaders;
|
||||
import org.apache.http.client.protocol.RequestProxyAuthentication;
|
||||
import org.apache.http.client.protocol.RequestTargetAuthentication;
|
||||
import org.apache.http.client.protocol.ResponseAuthCache;
|
||||
import org.apache.http.client.protocol.ResponseProcessCookies;
|
||||
import org.apache.http.conn.ClientConnectionManager;
|
||||
import org.apache.http.params.CoreConnectionPNames;
|
||||
|
@ -198,7 +197,6 @@ public class DefaultHttpClient extends AbstractHttpClient {
|
|||
* <li>{@link RequestAddCookies}</li>
|
||||
* <li>{@link ResponseProcessCookies}</li>
|
||||
* <li>{@link RequestAuthCache}</li>
|
||||
* <li>{@link ResponseAuthCache}</li>
|
||||
* <li>{@link RequestTargetAuthentication}</li>
|
||||
* <li>{@link RequestProxyAuthentication}</li>
|
||||
* </ul>
|
||||
|
@ -221,7 +219,6 @@ public class DefaultHttpClient extends AbstractHttpClient {
|
|||
httpproc.addInterceptor(new ResponseProcessCookies());
|
||||
// HTTP authentication interceptors
|
||||
httpproc.addInterceptor(new RequestAuthCache());
|
||||
httpproc.addInterceptor(new ResponseAuthCache());
|
||||
httpproc.addInterceptor(new RequestTargetAuthentication());
|
||||
httpproc.addInterceptor(new RequestProxyAuthentication());
|
||||
return httpproc;
|
||||
|
|
|
@ -184,9 +184,9 @@ public class DefaultRequestDirector implements RequestDirector {
|
|||
/** The currently allocated connection. */
|
||||
protected ManagedClientConnection managedConn;
|
||||
|
||||
protected AuthState targetAuthState;
|
||||
protected final AuthState targetAuthState;
|
||||
|
||||
protected AuthState proxyAuthState;
|
||||
protected final AuthState proxyAuthState;
|
||||
|
||||
private final HttpAuthenticator authenticator;
|
||||
|
||||
|
@ -351,6 +351,8 @@ public class DefaultRequestDirector implements RequestDirector {
|
|||
|
||||
this.execCount = 0;
|
||||
this.redirectCount = 0;
|
||||
this.targetAuthState = new AuthState();
|
||||
this.proxyAuthState = new AuthState();
|
||||
this.maxRedirects = this.params.getIntParameter(ClientPNames.MAX_REDIRECTS, 100);
|
||||
}
|
||||
|
||||
|
@ -400,16 +402,8 @@ public class DefaultRequestDirector implements RequestDirector {
|
|||
HttpContext context)
|
||||
throws HttpException, IOException {
|
||||
|
||||
targetAuthState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
|
||||
if (targetAuthState == null) {
|
||||
targetAuthState = new AuthState();
|
||||
context.setAttribute(ClientContext.TARGET_AUTH_STATE, targetAuthState);
|
||||
}
|
||||
proxyAuthState = (AuthState) context.getAttribute(ClientContext.PROXY_AUTH_STATE);
|
||||
if (proxyAuthState == null) {
|
||||
proxyAuthState = new AuthState();
|
||||
context.setAttribute(ClientContext.PROXY_AUTH_STATE, proxyAuthState);
|
||||
}
|
||||
context.setAttribute(ClientContext.TARGET_AUTH_STATE, targetAuthState);
|
||||
context.setAttribute(ClientContext.PROXY_AUTH_STATE, proxyAuthState);
|
||||
|
||||
HttpRequest orig = request;
|
||||
RequestWrapper origWrapper = wrapRequest(orig);
|
||||
|
@ -910,7 +904,7 @@ public class DefaultRequestDirector implements RequestDirector {
|
|||
}
|
||||
|
||||
if (HttpClientParams.isAuthenticating(this.params)) {
|
||||
if (this.authenticator.isAuthenticationRequested(response,
|
||||
if (this.authenticator.isAuthenticationRequested(proxy, response,
|
||||
this.proxyAuthStrategy, this.proxyAuthState, context)) {
|
||||
if (this.authenticator.authenticate(proxy, response,
|
||||
this.proxyAuthStrategy, this.proxyAuthState, context)) {
|
||||
|
@ -1107,19 +1101,16 @@ public class DefaultRequestDirector implements RequestDirector {
|
|||
}
|
||||
|
||||
if (HttpClientParams.isAuthenticating(params)) {
|
||||
if (this.authenticator.isAuthenticationRequested(response,
|
||||
HttpHost target = (HttpHost) context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
|
||||
if (target == null) {
|
||||
target = route.getTargetHost();
|
||||
}
|
||||
if (target.getPort() < 0) {
|
||||
Scheme scheme = connManager.getSchemeRegistry().getScheme(target);
|
||||
target = new HttpHost(target.getHostName(), scheme.getDefaultPort(), target.getSchemeName());
|
||||
}
|
||||
if (this.authenticator.isAuthenticationRequested(target, response,
|
||||
this.targetAuthStrategy, this.targetAuthState, context)) {
|
||||
|
||||
HttpHost target = (HttpHost)
|
||||
context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
|
||||
if (target == null) {
|
||||
target = route.getTargetHost();
|
||||
}
|
||||
if (target.getPort() < 0) {
|
||||
Scheme scheme = connManager.getSchemeRegistry().getScheme(target);
|
||||
target = new HttpHost(
|
||||
target.getHostName(), scheme.getDefaultPort(), target.getSchemeName());
|
||||
}
|
||||
if (this.authenticator.authenticate(target, response,
|
||||
this.targetAuthStrategy, this.targetAuthState, context)) {
|
||||
// Re-try the same request via the same route
|
||||
|
@ -1129,9 +1120,9 @@ public class DefaultRequestDirector implements RequestDirector {
|
|||
}
|
||||
}
|
||||
|
||||
if (this.authenticator.isAuthenticationRequested(response,
|
||||
HttpHost proxy = route.getProxyHost();
|
||||
if (this.authenticator.isAuthenticationRequested(proxy, response,
|
||||
this.proxyAuthStrategy, this.proxyAuthState, context)) {
|
||||
HttpHost proxy = route.getProxyHost();
|
||||
if (this.authenticator.authenticate(proxy, response,
|
||||
this.proxyAuthStrategy, this.proxyAuthState, context)) {
|
||||
// Re-try the same request via the same route
|
||||
|
|
|
@ -58,17 +58,19 @@ public class HttpAuthenticator {
|
|||
}
|
||||
|
||||
public boolean isAuthenticationRequested(
|
||||
final HttpHost host,
|
||||
final HttpResponse response,
|
||||
final AuthenticationStrategy authStrategy,
|
||||
final AuthState authState,
|
||||
final HttpContext context) {
|
||||
if (authStrategy.isAuthenticationRequested(response, context)) {
|
||||
if (authStrategy.isAuthenticationRequested(host, response, context)) {
|
||||
return true;
|
||||
} else {
|
||||
switch (authState.getState()) {
|
||||
case CHALLENGED:
|
||||
case HANDSHAKE:
|
||||
authState.setState(AuthProtocolState.SUCCESS);
|
||||
authStrategy.authSucceeded(host, authState.getAuthScheme(), context);
|
||||
break;
|
||||
case SUCCESS:
|
||||
break;
|
||||
|
@ -89,7 +91,7 @@ public class HttpAuthenticator {
|
|||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug(host.toHostString() + " requested authentication");
|
||||
}
|
||||
Map<String, Header> challenges = authStrategy.getChallenges(response, context);
|
||||
Map<String, Header> challenges = authStrategy.getChallenges(host, response, context);
|
||||
if (challenges.isEmpty()) {
|
||||
this.log.debug("Response contains no authentication challenges");
|
||||
return false;
|
||||
|
@ -105,6 +107,7 @@ public class HttpAuthenticator {
|
|||
case CHALLENGED:
|
||||
if (authScheme == null) {
|
||||
this.log.debug("Auth scheme is null");
|
||||
authStrategy.authFailed(host, authState.getAuthScheme(), context);
|
||||
authState.reset();
|
||||
authState.setState(AuthProtocolState.FAILURE);
|
||||
return false;
|
||||
|
@ -118,6 +121,7 @@ public class HttpAuthenticator {
|
|||
authScheme.processChallenge(challenge);
|
||||
if (authScheme.isComplete()) {
|
||||
this.log.debug("Authentication failed");
|
||||
authStrategy.authFailed(host, authState.getAuthScheme(), context);
|
||||
authState.reset();
|
||||
authState.setState(AuthProtocolState.FAILURE);
|
||||
return false;
|
||||
|
|
|
@ -176,7 +176,7 @@ public class ProxyClient {
|
|||
}
|
||||
|
||||
if (HttpClientParams.isAuthenticating(this.params)) {
|
||||
if (this.authenticator.isAuthenticationRequested(response,
|
||||
if (this.authenticator.isAuthenticationRequested(proxy, response,
|
||||
this.proxyAuthStrategy, this.proxyAuthState, context)) {
|
||||
if (this.authenticator.authenticate(proxy, response,
|
||||
this.proxyAuthStrategy, this.proxyAuthState, context)) {
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.apache.http.protocol.HttpContext;
|
|||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
@Deprecated
|
||||
public class TestResponseAuthCache {
|
||||
|
||||
private HttpHost target;
|
||||
|
|
|
@ -37,10 +37,12 @@ import org.apache.http.HttpStatus;
|
|||
import org.apache.http.HttpVersion;
|
||||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthOption;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.AuthSchemeRegistry;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||
import org.apache.http.auth.params.AuthPNames;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.CredentialsProvider;
|
||||
import org.apache.http.client.params.AuthPolicy;
|
||||
import org.apache.http.client.protocol.ClientContext;
|
||||
|
@ -54,6 +56,7 @@ import org.apache.http.protocol.BasicHttpContext;
|
|||
import org.apache.http.protocol.HttpContext;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
/**
|
||||
* Simple tests for {@link AuthenticationStrategyImpl}.
|
||||
|
@ -63,37 +66,42 @@ public class TestAuthenticationStrategy {
|
|||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testIsAuthenticationRequestedInvalidInput() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpHost host = new HttpHost("localhost", 80);
|
||||
HttpContext context = new BasicHttpContext();
|
||||
authStrategy.isAuthenticationRequested(null, context);
|
||||
authStrategy.isAuthenticationRequested(host, null, context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTargetAuthRequested() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
HttpHost host = new HttpHost("localhost", 80);
|
||||
HttpContext context = new BasicHttpContext();
|
||||
Assert.assertTrue(authStrategy.isAuthenticationRequested(response, context));
|
||||
Assert.assertTrue(authStrategy.isAuthenticationRequested(host, response, context));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProxyAuthRequested() throws Exception {
|
||||
ProxyAuthenticationStrategy authStrategy = new ProxyAuthenticationStrategy();
|
||||
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, "UNAUTHORIZED");
|
||||
HttpHost host = new HttpHost("localhost", 80);
|
||||
HttpContext context = new BasicHttpContext();
|
||||
Assert.assertTrue(authStrategy.isAuthenticationRequested(response, context));
|
||||
Assert.assertTrue(authStrategy.isAuthenticationRequested(host, response, context));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testGetChallengesInvalidInput() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpHost host = new HttpHost("localhost", 80);
|
||||
HttpContext context = new BasicHttpContext();
|
||||
authStrategy.getChallenges(null, context);
|
||||
authStrategy.getChallenges(host, null, context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetChallenges() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpContext context = new BasicHttpContext();
|
||||
HttpHost host = new HttpHost("localhost", 80);
|
||||
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
Header h1 = new BasicHeader(AUTH.WWW_AUTH, " Basic realm=\"test\"");
|
||||
Header h2 = new BasicHeader(AUTH.WWW_AUTH, "\t\tDigest realm=\"realm1\", nonce=\"1234\"");
|
||||
|
@ -102,7 +110,7 @@ public class TestAuthenticationStrategy {
|
|||
response.addHeader(h2);
|
||||
response.addHeader(h3);
|
||||
|
||||
Map<String, Header> challenges = authStrategy.getChallenges(response, context);
|
||||
Map<String, Header> challenges = authStrategy.getChallenges(host, response, context);
|
||||
|
||||
Assert.assertNotNull(challenges);
|
||||
Assert.assertEquals(3, challenges.size());
|
||||
|
@ -290,4 +298,141 @@ public class TestAuthenticationStrategy {
|
|||
Assert.assertTrue(option1.getAuthScheme() instanceof BasicScheme);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSucceededInvalidInput() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpHost authhost = new HttpHost("locahost", 80);
|
||||
BasicScheme authScheme = new BasicScheme();
|
||||
HttpContext context = new BasicHttpContext();
|
||||
try {
|
||||
authStrategy.authSucceeded(null, authScheme, context);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
}
|
||||
try {
|
||||
authStrategy.authSucceeded(authhost, null, context);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
}
|
||||
try {
|
||||
authStrategy.authSucceeded(authhost, authScheme, null);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSucceeded() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpHost authhost = new HttpHost("somehost", 80);
|
||||
BasicScheme authScheme = new BasicScheme();
|
||||
authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test"));
|
||||
|
||||
AuthCache authCache = Mockito.mock(AuthCache.class);
|
||||
|
||||
HttpContext context = new BasicHttpContext();
|
||||
context.setAttribute(ClientContext.AUTH_CACHE, authCache);
|
||||
|
||||
authStrategy.authSucceeded(authhost, authScheme, context);
|
||||
Mockito.verify(authCache).put(authhost, authScheme);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthSucceededNoCache() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpHost authhost = new HttpHost("somehost", 80);
|
||||
BasicScheme authScheme = new BasicScheme();
|
||||
authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test"));
|
||||
|
||||
HttpContext context = new BasicHttpContext();
|
||||
context.setAttribute(ClientContext.AUTH_CACHE, null);
|
||||
|
||||
authStrategy.authSucceeded(authhost, authScheme, context);
|
||||
AuthCache authCache = (AuthCache) context.getAttribute(ClientContext.AUTH_CACHE);
|
||||
Assert.assertNotNull(authCache);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthScemeNotCompleted() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpHost authhost = new HttpHost("somehost", 80);
|
||||
BasicScheme authScheme = new BasicScheme();
|
||||
|
||||
AuthCache authCache = Mockito.mock(AuthCache.class);
|
||||
|
||||
HttpContext context = new BasicHttpContext();
|
||||
context.setAttribute(ClientContext.AUTH_CACHE, authCache);
|
||||
|
||||
authStrategy.authSucceeded(authhost, authScheme, context);
|
||||
Mockito.verify(authCache, Mockito.never()).put(authhost, authScheme);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthScemeNonCacheable() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpHost authhost = new HttpHost("somehost", 80);
|
||||
AuthScheme authScheme = Mockito.mock(AuthScheme.class);
|
||||
Mockito.when(authScheme.isComplete()).thenReturn(true);
|
||||
Mockito.when(authScheme.getSchemeName()).thenReturn("whatever");
|
||||
|
||||
AuthCache authCache = Mockito.mock(AuthCache.class);
|
||||
|
||||
HttpContext context = new BasicHttpContext();
|
||||
context.setAttribute(ClientContext.AUTH_CACHE, authCache);
|
||||
|
||||
authStrategy.authSucceeded(authhost, authScheme, context);
|
||||
Mockito.verify(authCache, Mockito.never()).put(authhost, authScheme);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthFailedInvalidInput() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpHost authhost = new HttpHost("locahost", 80);
|
||||
BasicScheme authScheme = new BasicScheme();
|
||||
HttpContext context = new BasicHttpContext();
|
||||
try {
|
||||
authStrategy.authFailed(null, authScheme, context);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
}
|
||||
try {
|
||||
authStrategy.authFailed(authhost, null, context);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
}
|
||||
try {
|
||||
authStrategy.authFailed(authhost, authScheme, null);
|
||||
Assert.fail("IllegalArgumentException expected");
|
||||
} catch (IllegalArgumentException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthFailed() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpHost authhost = new HttpHost("somehost", 80);
|
||||
BasicScheme authScheme = new BasicScheme();
|
||||
authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test"));
|
||||
|
||||
AuthCache authCache = Mockito.mock(AuthCache.class);
|
||||
|
||||
HttpContext context = new BasicHttpContext();
|
||||
context.setAttribute(ClientContext.AUTH_CACHE, authCache);
|
||||
|
||||
authStrategy.authFailed(authhost, authScheme, context);
|
||||
Mockito.verify(authCache).remove(authhost);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthFailedNoCache() throws Exception {
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
HttpHost authhost = new HttpHost("somehost", 80);
|
||||
BasicScheme authScheme = new BasicScheme();
|
||||
|
||||
HttpContext context = new BasicHttpContext();
|
||||
context.setAttribute(ClientContext.AUTH_CACHE, null);
|
||||
|
||||
authStrategy.authFailed(authhost, authScheme, context);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -345,9 +345,10 @@ public class TestClientAuthentication extends BasicServerTestBase {
|
|||
|
||||
@Override
|
||||
public boolean isAuthenticationRequested(
|
||||
final HttpHost host,
|
||||
final HttpResponse response,
|
||||
final HttpContext context) {
|
||||
boolean res = super.isAuthenticationRequested(response, context);
|
||||
boolean res = super.isAuthenticationRequested(host, response, context);
|
||||
if (res == true) {
|
||||
synchronized (this) {
|
||||
this.count++;
|
||||
|
|
|
@ -36,11 +36,13 @@ import org.apache.http.HttpVersion;
|
|||
import org.apache.http.auth.AUTH;
|
||||
import org.apache.http.auth.AuthOption;
|
||||
import org.apache.http.auth.AuthProtocolState;
|
||||
import org.apache.http.auth.AuthScheme;
|
||||
import org.apache.http.auth.AuthSchemeRegistry;
|
||||
import org.apache.http.auth.AuthScope;
|
||||
import org.apache.http.auth.AuthState;
|
||||
import org.apache.http.auth.Credentials;
|
||||
import org.apache.http.auth.MalformedChallengeException;
|
||||
import org.apache.http.client.AuthCache;
|
||||
import org.apache.http.client.AuthenticationStrategy;
|
||||
import org.apache.http.client.protocol.ClientContext;
|
||||
import org.apache.http.impl.auth.BasicScheme;
|
||||
|
@ -51,6 +53,7 @@ import org.apache.http.impl.auth.NTLMSchemeFactory;
|
|||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicHttpResponse;
|
||||
import org.apache.http.protocol.BasicHttpContext;
|
||||
import org.apache.http.protocol.ExecutionContext;
|
||||
import org.apache.http.protocol.HttpContext;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
@ -61,17 +64,27 @@ public class TestHttpAuthenticator {
|
|||
|
||||
private AuthenticationStrategy authStrategy;
|
||||
private AuthState authState;
|
||||
private AuthScheme authScheme;
|
||||
private HttpContext context;
|
||||
private HttpHost host;
|
||||
private HttpHost proxy;
|
||||
private Credentials credentials;
|
||||
private BasicCredentialsProvider credentialsProvider;
|
||||
private AuthSchemeRegistry authSchemeRegistry;
|
||||
private AuthCache authCache;
|
||||
private HttpAuthenticator httpAuthenticator;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
public void setUp() throws Exception {
|
||||
this.authStrategy = Mockito.mock(AuthenticationStrategy.class);
|
||||
this.authState = new AuthState();
|
||||
this.authScheme = new BasicScheme();
|
||||
this.authScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "Basic realm=test"));
|
||||
this.context = new BasicHttpContext();
|
||||
this.host = new HttpHost("localhost", 80);
|
||||
this.proxy = new HttpHost("localhost", 8888);
|
||||
this.context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, this.host);
|
||||
this.context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, this.proxy);
|
||||
this.credentials = Mockito.mock(Credentials.class);
|
||||
this.credentialsProvider = new BasicCredentialsProvider();
|
||||
this.credentialsProvider.setCredentials(AuthScope.ANY, this.credentials);
|
||||
|
@ -81,6 +94,8 @@ public class TestHttpAuthenticator {
|
|||
this.authSchemeRegistry.register("digest", new DigestSchemeFactory());
|
||||
this.authSchemeRegistry.register("ntlm", new NTLMSchemeFactory());
|
||||
this.context.setAttribute(ClientContext.AUTHSCHEME_REGISTRY, this.authSchemeRegistry);
|
||||
this.authCache = Mockito.mock(AuthCache.class);
|
||||
this.context.setAttribute(ClientContext.AUTH_CACHE, this.authCache);
|
||||
this.httpAuthenticator = new HttpAuthenticator();
|
||||
}
|
||||
|
||||
|
@ -88,53 +103,65 @@ public class TestHttpAuthenticator {
|
|||
public void testAuthenticationRequested() throws Exception {
|
||||
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
Mockito.when(this.authStrategy.isAuthenticationRequested(
|
||||
Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class))).thenReturn(Boolean.TRUE);
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class))).thenReturn(Boolean.TRUE);
|
||||
|
||||
Assert.assertTrue(this.httpAuthenticator.isAuthenticationRequested(
|
||||
response, this.authStrategy, this.authState, this.context));
|
||||
this.host, response, this.authStrategy, this.authState, this.context));
|
||||
|
||||
Mockito.verify(this.authStrategy).isAuthenticationRequested(response, this.context);
|
||||
Mockito.verify(this.authStrategy).isAuthenticationRequested(this.host, response, this.context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticationNotRequestedUnchallenged() throws Exception {
|
||||
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
|
||||
Mockito.when(this.authStrategy.isAuthenticationRequested(
|
||||
Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE);
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE);
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.isAuthenticationRequested(
|
||||
response, this.authStrategy, this.authState, this.context));
|
||||
this.host, response, this.authStrategy, this.authState, this.context));
|
||||
Assert.assertEquals(AuthProtocolState.UNCHALLENGED, this.authState.getState());
|
||||
|
||||
Mockito.verify(this.authStrategy).isAuthenticationRequested(response, this.context);
|
||||
Mockito.verify(this.authStrategy).isAuthenticationRequested(this.host, response, this.context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticationNotRequestedSuccess1() throws Exception {
|
||||
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
|
||||
Mockito.when(this.authStrategy.isAuthenticationRequested(
|
||||
Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE);
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE);
|
||||
this.authState.update(this.authScheme, this.credentials);
|
||||
this.authState.setState(AuthProtocolState.CHALLENGED);
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.isAuthenticationRequested(
|
||||
response, this.authStrategy, this.authState, this.context));
|
||||
this.host, response, this.authStrategy, this.authState, this.context));
|
||||
Assert.assertEquals(AuthProtocolState.SUCCESS, this.authState.getState());
|
||||
|
||||
Mockito.verify(this.authStrategy).isAuthenticationRequested(response, this.context);
|
||||
Mockito.verify(this.authStrategy).isAuthenticationRequested(this.host, response, this.context);
|
||||
Mockito.verify(this.authStrategy).authSucceeded(this.host, this.authScheme, this.context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAuthenticationNotRequestedSuccess2() throws Exception {
|
||||
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
|
||||
Mockito.when(this.authStrategy.isAuthenticationRequested(
|
||||
Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE);
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class))).thenReturn(Boolean.FALSE);
|
||||
this.authState.update(this.authScheme, this.credentials);
|
||||
this.authState.setState(AuthProtocolState.HANDSHAKE);
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.isAuthenticationRequested(
|
||||
response, this.authStrategy, this.authState, this.context));
|
||||
this.host, response, this.authStrategy, this.authState, this.context));
|
||||
Assert.assertEquals(AuthProtocolState.SUCCESS, this.authState.getState());
|
||||
|
||||
Mockito.verify(this.authStrategy).isAuthenticationRequested(response, this.context);
|
||||
Mockito.verify(this.authStrategy).isAuthenticationRequested(this.host, response, this.context);
|
||||
Mockito.verify(this.authStrategy).authSucceeded(this.host, this.authScheme, this.context);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -168,6 +195,7 @@ public class TestHttpAuthenticator {
|
|||
HttpResponse response = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_UNAUTHORIZED, "UNAUTHORIZED");
|
||||
|
||||
Mockito.when(this.authStrategy.getChallenges(
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class))).thenReturn(new HashMap<String, Header>());
|
||||
|
||||
|
@ -228,6 +256,7 @@ public class TestHttpAuthenticator {
|
|||
response.addHeader(new BasicHeader(AUTH.WWW_AUTH, "Digest realm=\"realm1\", nonce=\"1234\""));
|
||||
|
||||
this.authState.setState(AuthProtocolState.CHALLENGED);
|
||||
this.authState.update(this.authScheme, this.credentials);
|
||||
|
||||
TargetAuthenticationStrategy authStrategy = new TargetAuthenticationStrategy();
|
||||
|
||||
|
@ -235,6 +264,8 @@ public class TestHttpAuthenticator {
|
|||
response, authStrategy, this.authState, this.context));
|
||||
|
||||
Assert.assertEquals(AuthProtocolState.FAILURE, this.authState.getState());
|
||||
|
||||
Mockito.verify(this.authCache).remove(host);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -271,6 +302,7 @@ public class TestHttpAuthenticator {
|
|||
|
||||
Assert.assertTrue(this.httpAuthenticator.authenticate(host,
|
||||
response, authStrategy, this.authState, this.context));
|
||||
|
||||
Assert.assertEquals(AuthProtocolState.HANDSHAKE, this.authState.getState());
|
||||
}
|
||||
|
||||
|
@ -306,7 +338,9 @@ public class TestHttpAuthenticator {
|
|||
this.authState.setState(AuthProtocolState.CHALLENGED);
|
||||
|
||||
Mockito.doThrow(new MalformedChallengeException()).when(this.authStrategy).getChallenges(
|
||||
Mockito.any(HttpResponse.class), Mockito.any(HttpContext.class));
|
||||
Mockito.any(HttpHost.class),
|
||||
Mockito.any(HttpResponse.class),
|
||||
Mockito.any(HttpContext.class));
|
||||
|
||||
Assert.assertFalse(this.httpAuthenticator.authenticate(host,
|
||||
response, this.authStrategy, this.authState, this.context));
|
||||
|
|
Loading…
Reference in New Issue