HTTPCLIENT-1107: deprecated AuthenticationHandler in favor of new AuthenticationStrategy

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1175433 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2011-09-25 17:27:22 +00:00
parent 70a34914ba
commit 145d0c1f3c
13 changed files with 721 additions and 110 deletions

View File

@ -0,0 +1,66 @@
/*
* ====================================================================
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.auth;
import org.apache.http.annotation.Immutable;
/**
* @since 4.2
*/
@Immutable
public final class AuthOption {
private final AuthScheme authScheme;
private final Credentials creds;
public AuthOption(final AuthScheme authScheme, final Credentials creds) {
super();
if (authScheme == null) {
throw new IllegalArgumentException("Auth scheme may not be null");
}
if (creds == null) {
throw new IllegalArgumentException("User credentials may not be null");
}
this.authScheme = authScheme;
this.creds = creds;
}
public AuthScheme getAuthScheme() {
return this.authScheme;
}
public Credentials getCredentials() {
return this.creds;
}
@Override
public String toString() {
return this.authScheme.toString();
}
}

View File

@ -47,7 +47,10 @@ import org.apache.http.protocol.HttpContext;
* from multiple threads.
*
* @since 4.0
*
* @deprecated use {@link AuthenticationStrategy}
*/
@Deprecated
public interface AuthenticationHandler {
/**

View File

@ -0,0 +1,97 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.client;
import java.util.Map;
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.MalformedChallengeException;
import org.apache.http.protocol.HttpContext;
/**
/**
* A handler for determining if an HTTP response represents an authentication challenge that was
* sent back to the client as a result of authentication failure.
* <p>
* Implementations of this interface must be thread-safe. Access to shared data must be
* synchronized as methods of this interface may be executed from multiple threads.
*
* @since 4.2
*/
public interface AuthenticationStrategy {
/**
* Determines if the given HTTP response response represents
* an authentication challenge that was sent back as a result
* of authentication failure
* @param response HTTP response.
* @param context HTTP context.
* @return <code>true</code> if user authentication is required,
* <code>false</code> otherwise.
*/
boolean isAuthenticationRequested(
HttpResponse response,
HttpContext context);
/**
* Extracts from the given HTTP response a collection of authentication
* challenges, each of which represents an authentication scheme supported
* by the authentication host.
*
* @param response HTTP response.
* @param context HTTP context.
* @return a collection of challenges keyed by names of corresponding
* authentication schemes.
* @throws MalformedChallengeException if one of the authentication
* challenges is not valid or malformed.
*/
Map<String, Header> getChallenges(
HttpResponse response,
HttpContext context) throws MalformedChallengeException;
/**
* 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 response HTTP response.
* @param context HTTP context.
* @return authentication scheme to use for authentication.
* @throws MalformedChallengeException if one of the authentication
* challenges is not valid or malformed.
*/
AuthOption select(
Map<String, Header> challenges,
HttpHost authhost,
HttpResponse response,
HttpContext context) throws MalformedChallengeException;
}

View File

@ -46,6 +46,7 @@ import org.apache.http.auth.AuthSchemeRegistry;
import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.client.AuthenticationHandler;
import org.apache.http.client.AuthenticationStrategy;
import org.apache.http.client.params.AuthPolicy;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.protocol.HTTP;
@ -56,7 +57,10 @@ import org.apache.http.util.CharArrayBuffer;
* Base class for {@link AuthenticationHandler} implementations.
*
* @since 4.0
*
* @deprecated use {@link AuthenticationStrategy}
*/
@Deprecated
@Immutable
public abstract class AbstractAuthenticationHandler implements AuthenticationHandler {

View File

@ -0,0 +1,122 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.impl.client;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.annotation.Immutable;
import org.apache.http.auth.AuthOption;
import org.apache.http.auth.AuthScheme;
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.AuthenticationHandler;
import org.apache.http.client.AuthenticationStrategy;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.protocol.HttpContext;
/**
* @since 4.2
*/
@SuppressWarnings("deprecation")
@Immutable
@Deprecated
class AuthenticationStrategyAdaptor implements AuthenticationStrategy {
private final Log log = LogFactory.getLog(getClass());
private final AuthenticationHandler handler;
@Deprecated
public AuthenticationStrategyAdaptor(final AuthenticationHandler handler) {
super();
this.handler = handler;
}
public boolean isAuthenticationRequested(final HttpResponse response, final HttpContext context) {
return this.handler.isAuthenticationRequested(response, context);
}
public Map<String, Header> getChallenges(
final HttpResponse response,
final HttpContext context) throws MalformedChallengeException {
return this.handler.getChallenges(response, context);
}
public AuthOption select(
final Map<String, Header> challenges,
final HttpHost authhost,
final HttpResponse response,
final HttpContext context) throws MalformedChallengeException {
CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(
ClientContext.CREDS_PROVIDER);
if (credsProvider == null) {
this.log.debug("Credentials provider not set in the context");
return null;
}
AuthScheme authScheme;
try {
authScheme = this.handler.selectScheme(challenges, response, context);
} catch (AuthenticationException ex) {
if (this.log.isWarnEnabled()) {
this.log.warn(ex.getMessage(), ex);
}
return null;
}
String id = authScheme.getSchemeName();
Header challenge = challenges.get(id.toLowerCase(Locale.US));
authScheme.processChallenge(challenge);
AuthScope authScope = new AuthScope(
authhost.getHostName(),
authhost.getPort(),
authScheme.getRealm(),
authScheme.getSchemeName());
Credentials credentials = credsProvider.getCredentials(authScope);
if (credentials != null) {
return new AuthOption(authScheme, credentials);
} else {
return null;
}
}
public AuthenticationHandler getHandler() {
return this.handler;
}
}

View File

@ -0,0 +1,200 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
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.Locale;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.FormattedHeader;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.annotation.Immutable;
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.Credentials;
import org.apache.http.auth.MalformedChallengeException;
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.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.CharArrayBuffer;
@Immutable
class AuthenticationStrategyImpl implements AuthenticationStrategy {
private final Log log = LogFactory.getLog(getClass());
private static final List<String> DEFAULT_SCHEME_PRIORITY =
Collections.unmodifiableList(Arrays.asList(new String[] {
AuthPolicy.SPNEGO,
AuthPolicy.NTLM,
AuthPolicy.DIGEST,
AuthPolicy.BASIC
}));
private final int challengeCode;
private final String headerName;
private final String prefParamName;
AuthenticationStrategyImpl(int challengeCode, final String headerName, final String prefParamName) {
super();
this.challengeCode = challengeCode;
this.headerName = headerName;
this.prefParamName = prefParamName;
}
public boolean isAuthenticationRequested(final HttpResponse response, final HttpContext context) {
if (response == null) {
throw new IllegalArgumentException("HTTP response may not be null");
}
int status = response.getStatusLine().getStatusCode();
return status == this.challengeCode;
}
public Map<String, Header> getChallenges(
final HttpResponse response,
final HttpContext context) throws MalformedChallengeException {
if (response == null) {
throw new IllegalArgumentException("HTTP response may not be null");
}
Header[] headers = response.getHeaders(this.headerName);
Map<String, Header> map = new HashMap<String, Header>(headers.length);
for (Header header : headers) {
CharArrayBuffer buffer;
int pos;
if (header instanceof FormattedHeader) {
buffer = ((FormattedHeader) header).getBuffer();
pos = ((FormattedHeader) header).getValuePos();
} else {
String s = header.getValue();
if (s == null) {
throw new MalformedChallengeException("Header value is null");
}
buffer = new CharArrayBuffer(s.length());
buffer.append(s);
pos = 0;
}
while (pos < buffer.length() && HTTP.isWhitespace(buffer.charAt(pos))) {
pos++;
}
int beginIndex = pos;
while (pos < buffer.length() && !HTTP.isWhitespace(buffer.charAt(pos))) {
pos++;
}
int endIndex = pos;
String s = buffer.substring(beginIndex, endIndex);
map.put(s.toLowerCase(Locale.US), header);
}
return map;
}
public AuthOption select(
final Map<String, Header> challenges,
final HttpHost authhost,
final HttpResponse response,
final HttpContext context) throws MalformedChallengeException {
if (challenges == null) {
throw new IllegalArgumentException("Map of auth challenges may not be null");
}
if (authhost == null) {
throw new IllegalArgumentException("Host may not be null");
}
if (response == null) {
throw new IllegalArgumentException("HTTP response may not be null");
}
if (context == null) {
throw new IllegalArgumentException("HTTP context may not be null");
}
AuthSchemeRegistry registry = (AuthSchemeRegistry) context.getAttribute(
ClientContext.AUTHSCHEME_REGISTRY);
if (registry == null) {
this.log.debug("Auth scheme registry not set in the context");
return null;
}
CredentialsProvider credsProvider = (CredentialsProvider) context.getAttribute(
ClientContext.CREDS_PROVIDER);
if (credsProvider == null) {
this.log.debug("Credentials provider not set in the context");
return null;
}
@SuppressWarnings("unchecked")
List<String> authPrefs = (List<String>) response.getParams().getParameter(this.prefParamName);
if (authPrefs == null) {
authPrefs = DEFAULT_SCHEME_PRIORITY;
}
if (this.log.isDebugEnabled()) {
this.log.debug("Authentication schemes in the order of preference: " + authPrefs);
}
for (String id: authPrefs) {
Header challenge = challenges.get(id.toLowerCase(Locale.US));
if (challenge != null) {
try {
AuthScheme authScheme = registry.getAuthScheme(id, response.getParams());
authScheme.processChallenge(challenge);
AuthScope authScope = new AuthScope(
authhost.getHostName(),
authhost.getPort(),
authScheme.getRealm(),
authScheme.getSchemeName());
Credentials credentials = credsProvider.getCredentials(authScope);
if (credentials != null) {
return new AuthOption(authScheme, credentials);
}
} catch (IllegalStateException e) {
if (this.log.isWarnEnabled()) {
this.log.warn("Authentication scheme " + id + " not supported");
// Try again
}
}
} else {
if (this.log.isDebugEnabled()) {
this.log.debug("Challenge for " + id + " authentication scheme not available");
// Try again
}
}
}
return null;
}
}

View File

@ -46,7 +46,10 @@ import org.apache.http.protocol.HttpContext;
* authentication.
*
* @since 4.0
*
* @deprecated use {@link ProxyAuthenticationStrategy}
*/
@Deprecated
@Immutable
public class DefaultProxyAuthenticationHandler extends AbstractAuthenticationHandler {

View File

@ -33,6 +33,7 @@ import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.ProtocolException;
import org.apache.http.annotation.Immutable;
import org.apache.http.client.RedirectHandler;
import org.apache.http.client.RedirectStrategy;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
@ -42,14 +43,15 @@ import org.apache.http.protocol.HttpContext;
/**
* @since 4.1
*/
@SuppressWarnings("deprecation")
@Immutable
@Deprecated
class DefaultRedirectStrategyAdaptor implements RedirectStrategy {
private final org.apache.http.client.RedirectHandler handler;
private final RedirectHandler handler;
@Deprecated
public DefaultRedirectStrategyAdaptor(final org.apache.http.client.RedirectHandler handler) {
public DefaultRedirectStrategyAdaptor(final RedirectHandler handler) {
super();
this.handler = handler;
}
@ -74,4 +76,8 @@ class DefaultRedirectStrategyAdaptor implements RedirectStrategy {
}
}
public RedirectHandler getHandler() {
return this.handler;
}
}

View File

@ -49,10 +49,11 @@ import org.apache.http.auth.AuthChallengeState;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthState;
import org.apache.http.client.AuthenticationHandler;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.AuthenticationStrategy;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.NonRepeatableRequestException;
import org.apache.http.client.RedirectException;
import org.apache.http.client.RedirectHandler;
import org.apache.http.client.RedirectStrategy;
import org.apache.http.client.RequestDirector;
import org.apache.http.client.UserTokenHandler;
@ -124,6 +125,7 @@ import org.apache.http.util.EntityUtils;
*
* @since 4.0
*/
@SuppressWarnings("deprecation")
@NotThreadSafe // e.g. managedConn
public class DefaultRequestDirector implements RequestDirector {
@ -152,17 +154,25 @@ public class DefaultRequestDirector implements RequestDirector {
/** The redirect handler. */
@Deprecated
protected final org.apache.http.client.RedirectHandler redirectHandler = null;
protected final RedirectHandler redirectHandler;
/** The redirect strategy. */
protected final RedirectStrategy redirectStrategy;
/** The target authentication handler. */
@Deprecated
protected final AuthenticationHandler targetAuthHandler;
/** The target authentication handler. */
protected final AuthenticationStrategy targetAuthStrategy;
/** The proxy authentication handler. */
@Deprecated
protected final AuthenticationHandler proxyAuthHandler;
/** The proxy authentication handler. */
protected final AuthenticationStrategy proxyAuthStrategy;
/** The user token handler. */
protected final UserTokenHandler userTokenHandler;
@ -195,7 +205,7 @@ public class DefaultRequestDirector implements RequestDirector {
final HttpRoutePlanner rouplan,
final HttpProcessor httpProcessor,
final HttpRequestRetryHandler retryHandler,
final org.apache.http.client.RedirectHandler redirectHandler,
final RedirectHandler redirectHandler,
final AuthenticationHandler targetAuthHandler,
final AuthenticationHandler proxyAuthHandler,
final UserTokenHandler userTokenHandler,
@ -203,13 +213,14 @@ public class DefaultRequestDirector implements RequestDirector {
this(LogFactory.getLog(DefaultRequestDirector.class),
requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler,
new DefaultRedirectStrategyAdaptor(redirectHandler),
targetAuthHandler, proxyAuthHandler, userTokenHandler, params);
new AuthenticationStrategyAdaptor(targetAuthHandler),
new AuthenticationStrategyAdaptor(proxyAuthHandler),
userTokenHandler,
params);
}
/**
* @since 4.1
*/
@Deprecated
public DefaultRequestDirector(
final Log log,
final HttpRequestExecutor requestExec,
@ -224,6 +235,32 @@ public class DefaultRequestDirector implements RequestDirector {
final AuthenticationHandler proxyAuthHandler,
final UserTokenHandler userTokenHandler,
final HttpParams params) {
this(LogFactory.getLog(DefaultRequestDirector.class),
requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler,
redirectStrategy,
new AuthenticationStrategyAdaptor(targetAuthHandler),
new AuthenticationStrategyAdaptor(proxyAuthHandler),
userTokenHandler,
params);
}
/**
* @since 4.2
*/
public DefaultRequestDirector(
final Log log,
final HttpRequestExecutor requestExec,
final ClientConnectionManager conman,
final ConnectionReuseStrategy reustrat,
final ConnectionKeepAliveStrategy kastrat,
final HttpRoutePlanner rouplan,
final HttpProcessor httpProcessor,
final HttpRequestRetryHandler retryHandler,
final RedirectStrategy redirectStrategy,
final AuthenticationStrategy targetAuthStrategy,
final AuthenticationStrategy proxyAuthStrategy,
final UserTokenHandler userTokenHandler,
final HttpParams params) {
if (log == null) {
throw new IllegalArgumentException
@ -261,13 +298,13 @@ public class DefaultRequestDirector implements RequestDirector {
throw new IllegalArgumentException
("Redirect strategy may not be null.");
}
if (targetAuthHandler == null) {
if (targetAuthStrategy == null) {
throw new IllegalArgumentException
("Target authentication handler may not be null.");
("Target authentication strategy may not be null.");
}
if (proxyAuthHandler == null) {
if (proxyAuthStrategy == null) {
throw new IllegalArgumentException
("Proxy authentication handler may not be null.");
("Proxy authentication strategy may not be null.");
}
if (userTokenHandler == null) {
throw new IllegalArgumentException
@ -279,27 +316,43 @@ public class DefaultRequestDirector implements RequestDirector {
}
this.log = log;
this.authenticator = new HttpAuthenticator(log);
this.requestExec = requestExec;
this.connManager = conman;
this.reuseStrategy = reustrat;
this.keepAliveStrategy = kastrat;
this.routePlanner = rouplan;
this.httpProcessor = httpProcessor;
this.retryHandler = retryHandler;
this.redirectStrategy = redirectStrategy;
this.targetAuthHandler = targetAuthHandler;
this.proxyAuthHandler = proxyAuthHandler;
this.userTokenHandler = userTokenHandler;
this.params = params;
this.requestExec = requestExec;
this.connManager = conman;
this.reuseStrategy = reustrat;
this.keepAliveStrategy = kastrat;
this.routePlanner = rouplan;
this.httpProcessor = httpProcessor;
this.retryHandler = retryHandler;
this.redirectStrategy = redirectStrategy;
this.targetAuthStrategy = targetAuthStrategy;
this.proxyAuthStrategy = proxyAuthStrategy;
this.userTokenHandler = userTokenHandler;
this.params = params;
this.managedConn = null;
if (redirectStrategy instanceof DefaultRedirectStrategyAdaptor) {
this.redirectHandler = ((DefaultRedirectStrategyAdaptor) redirectStrategy).getHandler();
} else {
this.redirectHandler = null;
}
if (targetAuthStrategy instanceof AuthenticationStrategyAdaptor) {
this.targetAuthHandler = ((AuthenticationStrategyAdaptor) targetAuthStrategy).getHandler();
} else {
this.targetAuthHandler = null;
}
if (proxyAuthStrategy instanceof AuthenticationStrategyAdaptor) {
this.proxyAuthHandler = ((AuthenticationStrategyAdaptor) proxyAuthStrategy).getHandler();
} else {
this.proxyAuthHandler = null;
}
this.managedConn = null;
this.execCount = 0;
this.redirectCount = 0;
this.maxRedirects = this.params.getIntParameter(ClientPNames.MAX_REDIRECTS, 100);
this.targetAuthState = new AuthState();
this.proxyAuthState = new AuthState();
} // constructor
}
private RequestWrapper wrapRequest(
@ -842,16 +895,11 @@ public class DefaultRequestDirector implements RequestDirector {
response.getStatusLine());
}
CredentialsProvider credsProvider = (CredentialsProvider)
context.getAttribute(ClientContext.CREDS_PROVIDER);
if (credsProvider != null && HttpClientParams.isAuthenticating(this.params)) {
if (HttpClientParams.isAuthenticating(this.params)) {
if (this.authenticator.isAuthenticationRequested(response,
this.proxyAuthHandler, this.proxyAuthState, context)) {
if (this.authenticator.authenticate(
proxy, response,
this.proxyAuthHandler, this.proxyAuthState,
credsProvider, context)) {
this.proxyAuthStrategy, this.proxyAuthState, context)) {
if (this.authenticator.authenticate(proxy, response,
this.proxyAuthStrategy, this.proxyAuthState, context)) {
// Retry request
if (this.reuseStrategy.keepAlive(response, context)) {
this.log.debug("Connection kept alive");
@ -1046,13 +1094,9 @@ public class DefaultRequestDirector implements RequestDirector {
return newRequest;
}
CredentialsProvider credsProvider = (CredentialsProvider)
context.getAttribute(ClientContext.CREDS_PROVIDER);
if (credsProvider != null && HttpClientParams.isAuthenticating(params)) {
if (HttpClientParams.isAuthenticating(params)) {
if (this.authenticator.isAuthenticationRequested(response,
this.targetAuthHandler, this.targetAuthState, context)) {
this.targetAuthStrategy, this.targetAuthState, context)) {
HttpHost target = (HttpHost)
context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
@ -1064,10 +1108,8 @@ public class DefaultRequestDirector implements RequestDirector {
target = new HttpHost(
target.getHostName(), scheme.getDefaultPort(), target.getSchemeName());
}
if (this.authenticator.authenticate(
target, response,
this.targetAuthHandler, this.targetAuthState,
credsProvider, context)) {
if (this.authenticator.authenticate(target, response,
this.targetAuthStrategy, this.targetAuthState, context)) {
// Re-try the same request via the same route
return roureq;
} else {
@ -1076,12 +1118,10 @@ public class DefaultRequestDirector implements RequestDirector {
}
if (this.authenticator.isAuthenticationRequested(response,
this.proxyAuthHandler, this.proxyAuthState, context)) {
this.proxyAuthStrategy, this.proxyAuthState, context)) {
HttpHost proxy = route.getProxyHost();
if (this.authenticator.authenticate(
proxy, response,
this.proxyAuthHandler, this.proxyAuthState,
credsProvider, context)) {
if (this.authenticator.authenticate(proxy, response,
this.proxyAuthStrategy, this.proxyAuthState, context)) {
// Re-try the same request via the same route
return roureq;
} else {

View File

@ -46,7 +46,10 @@ import org.apache.http.protocol.HttpContext;
* authentication.
*
* @since 4.0
*
* @deprecated use {@link TargetAuthenticationStrategy}
*/
@Deprecated
@Immutable
public class DefaultTargetAuthenticationHandler extends AbstractAuthenticationHandler {

View File

@ -36,14 +36,11 @@ import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthChallengeState;
import org.apache.http.auth.AuthOption;
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.Credentials;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.client.AuthenticationHandler;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.AuthenticationStrategy;
import org.apache.http.protocol.HttpContext;
public class HttpAuthenticator {
@ -61,10 +58,10 @@ public class HttpAuthenticator {
public boolean isAuthenticationRequested(
final HttpResponse response,
final AuthenticationHandler authHandler,
final AuthenticationStrategy authStrategy,
final AuthState authState,
final HttpContext context) {
if (authHandler.isAuthenticationRequested(response, context)) {
if (authStrategy.isAuthenticationRequested(response, context)) {
return true;
} else {
if (authState.getChallengeState() == AuthChallengeState.CHALLENGED) {
@ -79,79 +76,53 @@ public class HttpAuthenticator {
public boolean authenticate(
final HttpHost host,
final HttpResponse response,
final AuthenticationHandler authHandler,
final AuthenticationStrategy authStrategy,
final AuthState authState,
final CredentialsProvider credsProvider,
final HttpContext context) {
try {
if (this.log.isDebugEnabled()) {
this.log.debug(host.toHostString() + " requested authentication");
}
Map<String, Header> challenges = authHandler.getChallenges(response, context);
Map<String, Header> challenges = authStrategy.getChallenges(response, context);
if (challenges.isEmpty()) {
this.log.debug("Response contains no authentication challenges");
return false;
}
AuthScheme authScheme = authState.getAuthScheme();
if (authScheme == null) {
// Authentication not attempted before
authScheme = authHandler.selectScheme(challenges, response, context);
authState.setAuthScheme(authScheme);
}
String id = authScheme.getSchemeName();
Header challenge = challenges.get(id.toLowerCase(Locale.US));
if (challenge == null) {
// Retry authentication with a different scheme
authState.invalidate();
authScheme = authHandler.selectScheme(challenges, response, context);
authState.setAuthScheme(authScheme);
id = authScheme.getSchemeName();
challenge = challenges.get(id.toLowerCase(Locale.US));
}
authState.setChallengeState(AuthChallengeState.CHALLENGED);
authScheme.processChallenge(challenge);
this.log.debug("Authorization challenge processed");
AuthScope authScope = new AuthScope(
host.getHostName(),
host.getPort(),
authScheme.getRealm(),
authScheme.getSchemeName());
if (this.log.isDebugEnabled()) {
this.log.debug("Authentication scope: " + authScope);
}
Credentials creds = authState.getCredentials();
if (creds == null) {
creds = credsProvider.getCredentials(authScope);
if (this.log.isDebugEnabled()) {
if (creds != null) {
this.log.debug("Found credentials");
if (authScheme != null) {
String id = authScheme.getSchemeName();
Header challenge = challenges.get(id.toLowerCase(Locale.US));
if (challenge != null) {
this.log.debug("Authorization challenge processed");
authScheme.processChallenge(challenge);
if (authScheme.isComplete()) {
this.log.debug("Authentication failed");
authState.setChallengeState(AuthChallengeState.FAILURE);
authState.setCredentials(null);
return false;
} else {
this.log.debug("Credentials not found");
authState.setChallengeState(AuthChallengeState.CHALLENGED);
return true;
}
}
} else {
if (authScheme.isComplete()) {
this.log.debug("Authentication failed");
authState.setChallengeState(AuthChallengeState.FAILURE);
creds = null;
} else {
authState.invalidate();
// Retry authentication with a different scheme
}
}
authState.setCredentials(creds);
return creds != null;
AuthOption authOption = authStrategy.select(challenges, host, response, context);
if (authOption == null) {
return false;
}
authState.setAuthScheme(authOption.getAuthScheme());
authState.setCredentials(authOption.getCredentials());
authState.setChallengeState(AuthChallengeState.CHALLENGED);
return true;
} catch (MalformedChallengeException ex) {
if (this.log.isWarnEnabled()) {
this.log.warn("Malformed challenge: " + ex.getMessage());
}
authState.invalidate();
return false;
} catch (AuthenticationException ex) {
if (this.log.isWarnEnabled()) {
this.log.warn("Authentication error: " + ex.getMessage());
}
authState.invalidate();
return false;
}
}

View File

@ -0,0 +1,48 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.impl.client;
import org.apache.http.HttpStatus;
import org.apache.http.annotation.Immutable;
import org.apache.http.auth.AUTH;
import org.apache.http.auth.params.AuthPNames;
import org.apache.http.client.AuthenticationStrategy;
/**
* Default {@link AuthenticationStrategy} implementation for proxy host authentication.
*
* @since 4.2
*/
@Immutable
public class ProxyAuthenticationStrategy extends AuthenticationStrategyImpl {
public ProxyAuthenticationStrategy() {
super(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, AUTH.PROXY_AUTH, AuthPNames.PROXY_AUTH_PREF);
}
}

View File

@ -0,0 +1,48 @@
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.http.impl.client;
import org.apache.http.HttpStatus;
import org.apache.http.annotation.Immutable;
import org.apache.http.auth.AUTH;
import org.apache.http.auth.params.AuthPNames;
import org.apache.http.client.AuthenticationStrategy;
/**
* Default {@link AuthenticationStrategy} implementation for proxy host authentication.
*
* @since 4.2
*/
@Immutable
public class TargetAuthenticationStrategy extends AuthenticationStrategyImpl {
public TargetAuthenticationStrategy() {
super(HttpStatus.SC_UNAUTHORIZED, AUTH.WWW_AUTH, AuthPNames.TARGET_AUTH_PREF);
}
}