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:
parent
70a34914ba
commit
145d0c1f3c
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -47,7 +47,10 @@ import org.apache.http.protocol.HttpContext;
|
|||
* from multiple threads.
|
||||
*
|
||||
* @since 4.0
|
||||
*
|
||||
* @deprecated use {@link AuthenticationStrategy}
|
||||
*/
|
||||
@Deprecated
|
||||
public interface AuthenticationHandler {
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue