You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2015/07/04 15:42:40 UTC
svn commit: r1689155 [1/3] - in /httpcomponents/httpclient/trunk:
fluent-hc/src/main/java/org/apache/http/client/fluent/
httpclient-win/src/main/java/org/apache/http/impl/auth/win/
httpclient/src/main/java/org/apache/http/auth/ httpclient/src/main/java...
Author: olegk
Date: Sat Jul 4 13:42:40 2015
New Revision: 1689155
URL: http://svn.apache.org/r1689155
Log:
RFC 7231: redesign of HTTP authenticator and related classes
Added:
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeType.java (contents, props changed)
- copied, changed from r1687909, httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeState.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NonStandardAuthScheme.java (contents, props changed)
- copied, changed from r1687909, httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/ProxyAuthenticationStrategy.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/StandardAuthScheme.java (with props)
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java (contents, props changed)
- copied, changed from r1687909, httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AuthenticationStrategyImpl.java
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/auth/TestNonStandardHttpScheme.java (with props)
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/auth/TestStandardHttpScheme.java (with props)
Removed:
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeState.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/AuthSchemeBase.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/RFC2617Scheme.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AuthenticationStrategyImpl.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/ProxyAuthenticationStrategy.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/TargetAuthenticationStrategy.java
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/auth/TestRFC2617Scheme.java
Modified:
httpcomponents/httpclient/trunk/fluent-hc/src/main/java/org/apache/http/client/fluent/Executor.java
httpcomponents/httpclient/trunk/httpclient-win/src/main/java/org/apache/http/impl/auth/win/WindowsNegotiateScheme.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/AuthChallenge.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/AuthScheme.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/AuthenticationStrategy.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/AuthChallengeParser.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/BasicScheme.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestScheme.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestSchemeFactory.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/GGSSchemeBase.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/HttpAuthenticator.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/KerberosScheme.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NTLMScheme.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoScheme.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/ProxyClient.java
httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/execchain/MainClientExec.java
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/auth/TestAuthChallengeParser.java
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/auth/TestBasicScheme.java
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/auth/TestDigestScheme.java
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/auth/TestHttpAuthenticator.java
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestAuthenticationStrategy.java
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientAuthentication.java
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/integration/TestClientReauthentication.java
httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/execchain/TestMainClientExec.java
Modified: httpcomponents/httpclient/trunk/fluent-hc/src/main/java/org/apache/http/client/fluent/Executor.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/fluent-hc/src/main/java/org/apache/http/client/fluent/Executor.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/fluent-hc/src/main/java/org/apache/http/client/fluent/Executor.java (original)
+++ httpcomponents/httpclient/trunk/fluent-hc/src/main/java/org/apache/http/client/fluent/Executor.java Sat Jul 4 13:42:40 2015
@@ -29,13 +29,16 @@ package org.apache.http.client.fluent;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
+import java.util.Collections;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpHost;
-import org.apache.http.auth.AUTH;
+import org.apache.http.NameValuePair;
+import org.apache.http.auth.AuthChallenge;
import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.ChallengeType;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.auth.NTCredentials;
@@ -58,7 +61,6 @@ import org.apache.http.impl.client.Basic
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
-import org.apache.http.message.BasicHeader;
/**
* An Executor for fluent requests.
@@ -151,7 +153,7 @@ public class Executor {
public Executor authPreemptive(final HttpHost host) {
final BasicScheme basicScheme = new BasicScheme();
try {
- basicScheme.processChallenge(new BasicHeader(AUTH.WWW_AUTH, "BASIC "));
+ basicScheme.processChallenge(ChallengeType.TARGET, new AuthChallenge("basic", null, Collections.<NameValuePair>emptyList()));
} catch (final MalformedChallengeException ignore) {
}
this.authCache.put(host, basicScheme);
@@ -168,7 +170,7 @@ public class Executor {
public Executor authPreemptiveProxy(final HttpHost proxy) {
final BasicScheme basicScheme = new BasicScheme();
try {
- basicScheme.processChallenge(new BasicHeader(AUTH.PROXY_AUTH, "BASIC "));
+ basicScheme.processChallenge(ChallengeType.PROXY, new AuthChallenge("basic", null, Collections.<NameValuePair>emptyList()));
} catch (final MalformedChallengeException ignore) {
}
this.authCache.put(proxy, basicScheme);
Modified: httpcomponents/httpclient/trunk/httpclient-win/src/main/java/org/apache/http/impl/auth/win/WindowsNegotiateScheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient-win/src/main/java/org/apache/http/impl/auth/win/WindowsNegotiateScheme.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient-win/src/main/java/org/apache/http/impl/auth/win/WindowsNegotiateScheme.java (original)
+++ httpcomponents/httpclient/trunk/httpclient-win/src/main/java/org/apache/http/impl/auth/win/WindowsNegotiateScheme.java Sat Jul 4 13:42:40 2015
@@ -34,14 +34,16 @@ import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.annotation.NotThreadSafe;
import org.apache.http.auth.AUTH;
+import org.apache.http.auth.AuthChallenge;
import org.apache.http.auth.AuthenticationException;
+import org.apache.http.auth.ChallengeType;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.InvalidCredentialsException;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.routing.RouteInfo;
-import org.apache.http.impl.auth.AuthSchemeBase;
+import org.apache.http.impl.auth.NonStandardAuthScheme;
import org.apache.http.message.BufferedHeader;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.CharArrayBuffer;
@@ -68,7 +70,7 @@ import com.sun.jna.ptr.IntByReference;
* @since 4.4
*/
@NotThreadSafe
-public class WindowsNegotiateScheme extends AuthSchemeBase {
+public class WindowsNegotiateScheme extends NonStandardAuthScheme {
private final Log log = LogFactory.getLog(getClass());
@@ -79,13 +81,11 @@ public class WindowsNegotiateScheme exte
private CredHandle clientCred;
private CtxtHandle sspiContext;
private boolean continueNeeded;
- private String challenge;
public WindowsNegotiateScheme(final String scheme, final String servicePrincipalName) {
super();
this.scheme = (scheme == null) ? AuthSchemes.SPNEGO : scheme;
- this.challenge = null;
this.continueNeeded = true;
this.servicePrincipalName = servicePrincipalName;
@@ -123,35 +123,21 @@ public class WindowsNegotiateScheme exte
return scheme;
}
- // String parameters not supported
- @Override
- public String getParameter(final String name) {
- return null;
- }
-
- // NTLM/Negotiate do not support authentication realms
- @Override
- public String getRealm() {
- return null;
- }
-
@Override
public boolean isConnectionBased() {
return true;
}
@Override
- protected void parseChallenge(
- final CharArrayBuffer buffer,
- final int beginIndex,
- final int endIndex) throws MalformedChallengeException {
- this.challenge = buffer.substringTrimmed(beginIndex, endIndex);
-
- if (this.challenge.isEmpty()) {
+ public void processChallenge(
+ final ChallengeType challengeType, final AuthChallenge authChallenge) throws MalformedChallengeException {
+ update(challengeType, authChallenge);
+ final String challenge = getChallenge();
+ if (challenge.isEmpty()) {
if (clientCred != null) {
dispose(); // run cleanup first before throwing an exception otherwise can leak OS resources
if (continueNeeded) {
- throw new RuntimeException("Unexpected token");
+ throw new IllegalStateException("Unexpected token");
}
}
}
@@ -163,6 +149,7 @@ public class WindowsNegotiateScheme exte
final HttpRequest request,
final HttpContext context) throws AuthenticationException {
+ final String challenge = getChallenge();
final String response;
if (clientCred == null) {
// ?? We don't use the credentials, should we allow anything?
@@ -196,12 +183,12 @@ public class WindowsNegotiateScheme exte
throw ex;
}
}
- } else if (this.challenge == null || this.challenge.isEmpty()) {
+ } else if (challenge == null || challenge.isEmpty()) {
failAuthCleanup();
throw new AuthenticationException("Authentication Failed");
} else {
try {
- final byte[] continueTokenBytes = Base64.decodeBase64(this.challenge);
+ final byte[] continueTokenBytes = Base64.decodeBase64(challenge);
final SecBufferDesc continueTokenBuffer = new SecBufferDesc(
Sspi.SECBUFFER_TOKEN, continueTokenBytes);
final String targetName = getServicePrincipalName(context);
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/AuthChallenge.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/AuthChallenge.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/AuthChallenge.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/AuthChallenge.java Sat Jul 4 13:42:40 2015
@@ -27,6 +27,7 @@
package org.apache.http.auth;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -55,6 +56,10 @@ public final class AuthChallenge {
this.params = params != null ? Collections.unmodifiableList(new ArrayList<>(params)) : null;
}
+ public AuthChallenge(final String scheme, final NameValuePair... params) {
+ this(scheme, null, Arrays.asList(params));
+ }
+
public String getScheme() {
return scheme;
}
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/AuthScheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/AuthScheme.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/AuthScheme.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/AuthScheme.java Sat Jul 4 13:42:40 2015
@@ -60,9 +60,32 @@ public interface AuthScheme {
* may involve multiple challenge-response exchanges. Such schemes must be able
* to maintain the state information when dealing with sequential challenges
*
- * @param header the challenge header
+ * @param challengeType the challenge type
+ * @param authChallenge the auth challenge
+ *
+ * @since 5.0
+ */
+ void processChallenge(
+ ChallengeType challengeType,
+ AuthChallenge authChallenge) throws MalformedChallengeException;
+
+ /**
+ * Produces an authorization string for the given set of {@link Credentials}.
+ *
+ * @param credentials The credentials to be used for authentication
+ * @param request The request being authenticated
+ * @param context HTTP context
+ * @throws AuthenticationException if authorization string cannot
+ * be generated due to an authentication failure
+ *
+ * @return authorization header
+ *
+ * @since 5.0
*/
- void processChallenge(final Header header) throws MalformedChallengeException;
+ Header authenticate(
+ Credentials credentials,
+ HttpRequest request,
+ HttpContext context) throws AuthenticationException;
/**
* Returns textual designation of the given authentication scheme.
@@ -109,23 +132,4 @@ public interface AuthScheme {
*/
boolean isComplete();
- /**
- * Produces an authorization string for the given set of
- * {@link Credentials}.
- *
- * @param credentials The set of credentials to be used for athentication
- * @param request The request being authenticated
- * @param context HTTP context
- * @throws AuthenticationException if authorization string cannot
- * be generated due to an authentication failure
- *
- * @return the authorization string
- *
- * @since 5.0
- */
- Header authenticate(
- Credentials credentials,
- HttpRequest request,
- HttpContext context) throws AuthenticationException;
-
}
Copied: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeType.java (from r1687909, httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeState.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeType.java?p2=httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeType.java&p1=httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeState.java&r1=1687909&r2=1689155&rev=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeState.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeType.java Sat Jul 4 13:42:40 2015
@@ -27,11 +27,11 @@
package org.apache.http.auth;
/**
- * Challenge mode (TARGET or PROXY)
+ * Challenge type (TARGET or PROXY)
*
* @since 4.2
*/
-public enum ChallengeState {
+public enum ChallengeType {
TARGET, PROXY
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeType.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeType.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/auth/ChallengeType.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/AuthenticationStrategy.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/AuthenticationStrategy.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/AuthenticationStrategy.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/AuthenticationStrategy.java Sat Jul 4 13:42:40 2015
@@ -30,18 +30,16 @@ package org.apache.http.client;
import java.util.Map;
import java.util.Queue;
-import org.apache.http.Header;
import org.apache.http.HttpHost;
-import org.apache.http.HttpResponse;
+import org.apache.http.auth.AuthChallenge;
import org.apache.http.auth.AuthOption;
-import org.apache.http.auth.AuthScheme;
+import org.apache.http.auth.ChallengeType;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.protocol.HttpContext;
/**
-/**
- * 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.
+ * Strategy to select auth schemes in order of preference based on auth challenges
+ * presented by the opposite endpoint (target server or a proxy).
* <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.
@@ -51,80 +49,24 @@ import org.apache.http.protocol.HttpCont
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 authhost authentication host.
- * @param response HTTP response.
- * @param context HTTP context.
- * @return {@code true} if user authentication is required,
- * {@code false} otherwise.
- */
- boolean isAuthenticationRequested(
- HttpHost authhost,
- 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 authhost 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(
- HttpHost authhost,
- 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 challengeType challenge type.
+ * @param host authentication host.
* @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.
* @throws MalformedChallengeException if one of the authentication
* challenges is not valid or malformed.
+ *
+ * @since 5.0
*/
Queue<AuthOption> select(
- Map<String, Header> challenges,
- HttpHost authhost,
- HttpResponse response,
+ ChallengeType challengeType,
+ HttpHost host,
+ Map<String, AuthChallenge> challenges,
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);
-
}
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/AuthChallengeParser.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/AuthChallengeParser.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/AuthChallengeParser.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/AuthChallengeParser.java Sat Jul 4 13:42:40 2015
@@ -41,6 +41,8 @@ import org.apache.http.util.CharArrayBuf
public class AuthChallengeParser {
+ public static final AuthChallengeParser INSTANCE = new AuthChallengeParser();
+
private final TokenParser tokenParser = TokenParser.INSTANCE;
private final static char BLANK = ' ';
@@ -60,7 +62,7 @@ public class AuthChallengeParser {
if (buffer.charAt(cursor.getPos()) == BLANK) {
tokenParser.skipWhiteSpace(buffer, cursor);
}
- if (buffer.charAt(cursor.getPos()) == EQUAL_CHAR) {
+ if (!cursor.atEnd() && buffer.charAt(cursor.getPos()) == EQUAL_CHAR) {
cursor.updatePos(cursor.getPos() + 1);
final String value = tokenParser.parseValue(buffer, cursor, DELIMITER);
return new BasicNameValuePair(token, value);
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/BasicScheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/BasicScheme.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/BasicScheme.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/BasicScheme.java Sat Jul 4 13:42:40 2015
@@ -26,6 +26,10 @@
*/
package org.apache.http.impl.auth;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
import java.nio.charset.Charset;
import org.apache.commons.codec.binary.Base64;
@@ -34,13 +38,16 @@ import org.apache.http.Header;
import org.apache.http.HttpRequest;
import org.apache.http.annotation.NotThreadSafe;
import org.apache.http.auth.AUTH;
+import org.apache.http.auth.AuthChallenge;
import org.apache.http.auth.AuthenticationException;
+import org.apache.http.auth.ChallengeType;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.message.BufferedHeader;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.Args;
import org.apache.http.util.CharArrayBuffer;
+import org.apache.http.util.CharsetUtils;
import org.apache.http.util.EncodingUtils;
/**
@@ -49,18 +56,18 @@ import org.apache.http.util.EncodingUtil
* @since 4.0
*/
@NotThreadSafe
-public class BasicScheme extends RFC2617Scheme {
+public class BasicScheme extends StandardAuthScheme {
private static final long serialVersionUID = -1931571557597830536L;
- /** Whether the basic authentication process is complete */
+ private transient Charset charset;
private boolean complete;
/**
* @since 4.3
*/
- public BasicScheme(final Charset credentialsCharset) {
- super(credentialsCharset);
+ public BasicScheme(final Charset charset) {
+ this.charset = charset != null ? charset : Consts.ASCII;
this.complete = false;
}
@@ -68,64 +75,28 @@ public class BasicScheme extends RFC2617
this(Consts.ASCII);
}
- /**
- * Returns textual designation of the basic authentication scheme.
- *
- * @return {@code basic}
- */
@Override
public String getSchemeName() {
return "basic";
}
- /**
- * Processes the Basic challenge.
- *
- * @param header the challenge header
- *
- * @throws MalformedChallengeException is thrown if the authentication challenge
- * is malformed
- */
- @Override
public void processChallenge(
- final Header header) throws MalformedChallengeException {
- super.processChallenge(header);
+ final ChallengeType challengeType,
+ final AuthChallenge authChallenge) throws MalformedChallengeException {
+ update(challengeType, authChallenge);
this.complete = true;
}
- /**
- * Tests if the Basic authentication process has been completed.
- *
- * @return {@code true} if Basic authorization has been processed,
- * {@code false} otherwise.
- */
@Override
public boolean isComplete() {
return this.complete;
}
- /**
- * Returns {@code false}. Basic authentication scheme is request based.
- *
- * @return {@code false}.
- */
@Override
public boolean isConnectionBased() {
return false;
}
- /**
- * Produces basic authorization header for the given set of {@link Credentials}.
- *
- * @param credentials The set of credentials to be used for authentication
- * @param request The request being authenticated
- * @throws org.apache.http.auth.InvalidCredentialsException if authentication
- * credentials are not valid or not applicable for this authentication scheme
- * @throws AuthenticationException if authorization string cannot
- * be generated due to an authentication failure
- *
- * @return a basic authorization string
- */
@Override
public Header authenticate(
final Credentials credentials,
@@ -134,15 +105,6 @@ public class BasicScheme extends RFC2617
Args.notNull(credentials, "Credentials");
Args.notNull(request, "HTTP request");
- final StringBuilder tmp = new StringBuilder();
- tmp.append(credentials.getUserPrincipal().getName());
- tmp.append(":");
- tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());
-
- final Base64 base64codec = new Base64(0);
- final byte[] base64password = base64codec.encode(
- EncodingUtils.getBytes(tmp.toString(), getCredentialsCharset(request)));
-
final CharArrayBuffer buffer = new CharArrayBuffer(32);
if (isProxy()) {
buffer.append(AUTH.PROXY_AUTH_RESP);
@@ -150,16 +112,34 @@ public class BasicScheme extends RFC2617
buffer.append(AUTH.WWW_AUTH_RESP);
}
buffer.append(": Basic ");
- buffer.append(base64password, 0, base64password.length);
+ final StringBuilder tmp = new StringBuilder();
+ tmp.append(credentials.getUserPrincipal().getName());
+ tmp.append(":");
+ tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword());
+
+ final Base64 base64codec = new Base64(0);
+ final byte[] base64password = base64codec.encode(EncodingUtils.getBytes(tmp.toString(), charset.name()));
+
+ buffer.append(base64password, 0, base64password.length);
return new BufferedHeader(buffer);
}
- @Override
- public String toString() {
- final StringBuilder builder = new StringBuilder();
- builder.append("BASIC [complete=").append(complete)
- .append("]");
- return builder.toString();
+ private void writeObject(final ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ out.writeUTF(this.charset.name());
+ }
+
+ @SuppressWarnings("unchecked")
+ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ this.charset = CharsetUtils.get(in.readUTF());
+ if (this.charset == null) {
+ this.charset = Consts.ASCII;
+ }
+ }
+
+ private void readObjectNoData() throws ObjectStreamException {
}
+
}
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestScheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestScheme.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestScheme.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestScheme.java Sat Jul 4 13:42:40 2015
@@ -27,7 +27,6 @@
package org.apache.http.impl.auth;
import java.io.IOException;
-import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.ArrayList;
@@ -38,14 +37,15 @@ import java.util.Locale;
import java.util.Set;
import java.util.StringTokenizer;
-import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.annotation.NotThreadSafe;
import org.apache.http.auth.AUTH;
+import org.apache.http.auth.AuthChallenge;
import org.apache.http.auth.AuthenticationException;
+import org.apache.http.auth.ChallengeType;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.MalformedChallengeException;
import org.apache.http.message.BasicHeaderValueFormatter;
@@ -71,7 +71,7 @@ import org.apache.http.util.EncodingUtil
* @since 4.0
*/
@NotThreadSafe
-public class DigestScheme extends RFC2617Scheme {
+public class DigestScheme extends StandardAuthScheme {
private static final long serialVersionUID = 3883908186234566916L;
@@ -100,42 +100,23 @@ public class DigestScheme extends RFC261
private String a1;
private String a2;
- /**
- * @since 4.3
- */
- public DigestScheme(final Charset credentialsCharset) {
- super(credentialsCharset);
- this.complete = false;
- }
-
public DigestScheme() {
- this(Consts.ASCII);
+ this.complete = false;
}
- /**
- * Processes the Digest challenge.
- *
- * @param header the challenge header
- *
- * @throws MalformedChallengeException is thrown if the authentication challenge
- * is malformed
- */
@Override
public void processChallenge(
- final Header header) throws MalformedChallengeException {
- super.processChallenge(header);
- this.complete = true;
+ final ChallengeType challengeType,
+ final AuthChallenge authChallenge) throws MalformedChallengeException {
+ Args.notNull(challengeType, "ChallengeType");
+ Args.notNull(authChallenge, "AuthChallenge");
+ update(challengeType, authChallenge);
if (getParameters().isEmpty()) {
- throw new MalformedChallengeException("Authentication challenge is empty");
+ throw new MalformedChallengeException("Missing digest auth parameters");
}
+ this.complete = true;
}
- /**
- * Tests if the Digest authentication process has been completed.
- *
- * @return {@code true} if Digest authorization has been processed,
- * {@code false} otherwise.
- */
@Override
public boolean isComplete() {
final String s = getParameter("stale");
@@ -146,21 +127,11 @@ public class DigestScheme extends RFC261
}
}
- /**
- * Returns textual designation of the digest authentication scheme.
- *
- * @return {@code digest}
- */
@Override
public String getSchemeName() {
return "digest";
}
- /**
- * Returns {@code false}. Digest authentication scheme is request based.
- *
- * @return {@code false}.
- */
@Override
public boolean isConnectionBased() {
return false;
@@ -170,20 +141,6 @@ public class DigestScheme extends RFC261
getParameters().put(name, value);
}
- /**
- * Produces a digest authorization string for the given set of
- * {@link Credentials}, method name and URI.
- *
- * @param credentials A set of credentials to be used for athentication
- * @param request The request being authenticated
- *
- * @throws org.apache.http.auth.InvalidCredentialsException if authentication credentials
- * are not valid or not applicable for this authentication scheme
- * @throws AuthenticationException if authorization string cannot
- * be generated due to an authentication failure
- *
- * @return a digest authorization string
- */
@Override
public Header authenticate(
final Credentials credentials,
@@ -201,10 +158,6 @@ public class DigestScheme extends RFC261
// Add method name and request-URI to the parameter map
getParameters().put("methodname", request.getRequestLine().getMethod());
getParameters().put("uri", request.getRequestLine().getUri());
- final String charset = getParameter("charset");
- if (charset == null) {
- getParameters().put("charset", getCredentialsCharset(request));
- }
return createDigestHeader(credentials, request);
}
@@ -219,13 +172,6 @@ public class DigestScheme extends RFC261
}
}
- /**
- * Creates digest-response header as defined in RFC2617.
- *
- * @param credentials User credentials
- *
- * @return The digest-response as String.
- */
private Header createDigestHeader(
final Credentials credentials,
final HttpRequest request) throws AuthenticationException {
@@ -447,7 +393,6 @@ public class DigestScheme extends RFC261
return new String(buffer);
}
-
/**
* Creates a random cnonce value based on the current time.
*
@@ -460,14 +405,4 @@ public class DigestScheme extends RFC261
return encode(tmp);
}
- @Override
- public String toString() {
- final StringBuilder builder = new StringBuilder();
- builder.append("DIGEST [complete=").append(complete)
- .append(", nonce=").append(lastNonce)
- .append(", nc=").append(nounceCount)
- .append("]");
- return builder.toString();
- }
-
}
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestSchemeFactory.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestSchemeFactory.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestSchemeFactory.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/DigestSchemeFactory.java Sat Jul 4 13:42:40 2015
@@ -27,8 +27,6 @@
package org.apache.http.impl.auth;
-import java.nio.charset.Charset;
-
import org.apache.http.annotation.Immutable;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthSchemeProvider;
@@ -43,23 +41,9 @@ import org.apache.http.protocol.HttpCont
@Immutable
public class DigestSchemeFactory implements AuthSchemeProvider {
- private final Charset charset;
-
- /**
- * @since 4.3
- */
- public DigestSchemeFactory(final Charset charset) {
- super();
- this.charset = charset;
- }
-
- public DigestSchemeFactory() {
- this(null);
- }
-
@Override
public AuthScheme create(final HttpContext context) {
- return new DigestScheme(this.charset);
+ return new DigestScheme();
}
}
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/GGSSchemeBase.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/GGSSchemeBase.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/GGSSchemeBase.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/GGSSchemeBase.java Sat Jul 4 13:42:40 2015
@@ -37,7 +37,9 @@ import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.annotation.NotThreadSafe;
import org.apache.http.auth.AUTH;
+import org.apache.http.auth.AuthChallenge;
import org.apache.http.auth.AuthenticationException;
+import org.apache.http.auth.ChallengeType;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.InvalidCredentialsException;
import org.apache.http.auth.KerberosCredentials;
@@ -59,7 +61,7 @@ import org.ietf.jgss.Oid;
* @since 4.2
*/
@NotThreadSafe
-public abstract class GGSSchemeBase extends AuthSchemeBase {
+public abstract class GGSSchemeBase extends NonStandardAuthScheme {
enum State {
UNINITIATED,
@@ -70,7 +72,6 @@ public abstract class GGSSchemeBase exte
private final Log log = LogFactory.getLog(getClass());
- private final Base64 base64codec;
private final boolean stripPort;
private final boolean useCanonicalHostname;
@@ -82,7 +83,6 @@ public abstract class GGSSchemeBase exte
GGSSchemeBase(final boolean stripPort, final boolean useCanonicalHostname) {
super();
- this.base64codec = new Base64(0);
this.stripPort = stripPort;
this.useCanonicalHostname = useCanonicalHostname;
this.state = State.UNINITIATED;
@@ -96,6 +96,23 @@ public abstract class GGSSchemeBase exte
this(true,true);
}
+ public void processChallenge(
+ final ChallengeType challengeType,
+ final AuthChallenge authChallenge) throws MalformedChallengeException {
+ update(challengeType, authChallenge);
+ if (state == State.UNINITIATED) {
+ final String challenge = getChallenge();
+ token = Base64.decodeBase64(challenge.getBytes());
+ if (log.isDebugEnabled()) {
+ log.debug("Received token '" + token + "' from the auth server");
+ }
+ state = State.CHALLENGE_RECEIVED;
+ } else {
+ log.debug("Authentication already attempted");
+ state = State.FAILED;
+ }
+ }
+
protected GSSManager getManager() {
return GSSManager.getInstance();
}
@@ -211,7 +228,8 @@ public abstract class GGSSchemeBase exte
throw new AuthenticationException(gsse.getMessage());
}
case TOKEN_GENERATED:
- final String tokenstr = new String(base64codec.encode(token));
+ final Base64 codec = new Base64(0);
+ final String tokenstr = new String(codec.encode(token));
if (log.isDebugEnabled()) {
log.debug("Sending response '" + tokenstr + "' back to the auth server");
}
@@ -229,23 +247,6 @@ public abstract class GGSSchemeBase exte
}
}
- @Override
- protected void parseChallenge(
- final CharArrayBuffer buffer,
- final int beginIndex, final int endIndex) throws MalformedChallengeException {
- final String challenge = buffer.substringTrimmed(beginIndex, endIndex);
- if (log.isDebugEnabled()) {
- log.debug("Received challenge '" + challenge + "' from the auth server");
- }
- if (state == State.UNINITIATED) {
- token = Base64.decodeBase64(challenge.getBytes());
- state = State.CHALLENGE_RECEIVED;
- } else {
- log.debug("Authentication already attempted");
- state = State.FAILED;
- }
- }
-
private String resolveCanonicalHostname(final String host) throws UnknownHostException {
final InetAddress in = InetAddress.getByName(host);
final String canonicalServer = in.getCanonicalHostName();
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/HttpAuthenticator.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/HttpAuthenticator.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/HttpAuthenticator.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/HttpAuthenticator.java Sat Jul 4 13:42:40 2015
@@ -28,27 +28,40 @@
package org.apache.http.impl.auth;
import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Queue;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.http.FormattedHeader;
import org.apache.http.Header;
import org.apache.http.HttpException;
+import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.ParseException;
+import org.apache.http.auth.AuthChallenge;
import org.apache.http.auth.AuthOption;
import org.apache.http.auth.AuthProtocolState;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthState;
import org.apache.http.auth.AuthenticationException;
+import org.apache.http.auth.ChallengeType;
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.config.AuthSchemes;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.message.ParserCursor;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.Asserts;
+import org.apache.http.util.CharArrayBuffer;
/**
* @since 4.3
@@ -56,26 +69,39 @@ import org.apache.http.util.Asserts;
public class HttpAuthenticator {
private final Log log;
+ private final AuthChallengeParser parser;
public HttpAuthenticator(final Log log) {
super();
this.log = log != null ? log : LogFactory.getLog(getClass());
+ this.parser = new AuthChallengeParser();
}
public HttpAuthenticator() {
this(null);
}
- public boolean isAuthenticationRequested(
+ public boolean updateAuthState(
final HttpHost host,
+ final ChallengeType challengeType,
final HttpResponse response,
- final AuthenticationStrategy authStrategy,
final AuthState authState,
final HttpContext context) {
- if (authStrategy.isAuthenticationRequested(host, response, context)) {
+ final int challengeCode;
+ switch (challengeType) {
+ case TARGET:
+ challengeCode = HttpStatus.SC_UNAUTHORIZED;
+ break;
+ case PROXY:
+ challengeCode = HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED;
+ break;
+ default:
+ throw new IllegalStateException("Unexpected challenge type: " + challengeType);
+ }
+ if (response.getStatusLine().getStatusCode() == challengeCode) {
this.log.debug("Authentication required");
if (authState.getState() == AuthProtocolState.SUCCESS) {
- authStrategy.authFailed(host, authState.getAuthScheme(), context);
+ clearCache(host, context);
}
return true;
} else {
@@ -84,7 +110,7 @@ public class HttpAuthenticator {
case HANDSHAKE:
this.log.debug("Authentication succeeded");
authState.setState(AuthProtocolState.SUCCESS);
- authStrategy.authSucceeded(host, authState.getAuthScheme(), context);
+ updateCache(host, authState.getAuthScheme(), context);
break;
case SUCCESS:
break;
@@ -97,17 +123,55 @@ public class HttpAuthenticator {
public boolean handleAuthChallenge(
final HttpHost host,
+ final ChallengeType challengeType,
final HttpResponse response,
final AuthenticationStrategy authStrategy,
final AuthState authState,
final HttpContext context) {
+
+ if (this.log.isDebugEnabled()) {
+ this.log.debug(host.toHostString() + " requested authentication");
+ }
try {
- if (this.log.isDebugEnabled()) {
- this.log.debug(host.toHostString() + " requested authentication");
+ final Header[] headers = response.getHeaders(
+ challengeType == ChallengeType.PROXY ? HttpHeaders.PROXY_AUTHENTICATE : HttpHeaders.WWW_AUTHENTICATE);
+ final Map<String, AuthChallenge> challengeMap = new HashMap<>();
+ for (Header header: headers) {
+ final CharArrayBuffer buffer;
+ final int pos;
+ if (header instanceof FormattedHeader) {
+ buffer = ((FormattedHeader) header).getBuffer();
+ pos = ((FormattedHeader) header).getValuePos();
+ } else {
+ final String s = header.getValue();
+ if (s == null) {
+ continue;
+ }
+ buffer = new CharArrayBuffer(s.length());
+ buffer.append(s);
+ pos = 0;
+ }
+ final ParserCursor cursor = new ParserCursor(pos, buffer.length());
+ final List<AuthChallenge> authChallenges;
+ try {
+ authChallenges = parser.parse(buffer, cursor);
+ } catch (ParseException ex) {
+ if (this.log.isWarnEnabled()) {
+ this.log.warn("Malformed challenge: " + header.getValue());
+ }
+ continue;
+ }
+ for (AuthChallenge authChallenge: authChallenges) {
+ final String scheme = authChallenge.getScheme().toLowerCase(Locale.ROOT);
+ if (!challengeMap.containsKey(scheme)) {
+ challengeMap.put(scheme, authChallenge);
+ }
+ }
}
- final Map<String, Header> challenges = authStrategy.getChallenges(host, response, context);
- if (challenges.isEmpty()) {
- this.log.debug("Response contains no authentication challenges");
+ if (challengeMap.isEmpty()) {
+ this.log.debug("Response contains no valid authentication challenges");
+ clearCache(host, context);
+ authState.reset();
return false;
}
@@ -122,7 +186,7 @@ public class HttpAuthenticator {
case HANDSHAKE:
if (authScheme == null) {
this.log.debug("Auth scheme is null");
- authStrategy.authFailed(host, null, context);
+ clearCache(host, context);
authState.reset();
authState.setState(AuthProtocolState.FAILURE);
return false;
@@ -130,13 +194,13 @@ public class HttpAuthenticator {
case UNCHALLENGED:
if (authScheme != null) {
final String id = authScheme.getSchemeName();
- final Header challenge = challenges.get(id.toLowerCase(Locale.ROOT));
+ final AuthChallenge challenge = challengeMap.get(id.toLowerCase(Locale.ROOT));
if (challenge != null) {
this.log.debug("Authorization challenge processed");
- authScheme.processChallenge(challenge);
+ authScheme.processChallenge(challengeType, challenge);
if (authScheme.isComplete()) {
this.log.debug("Authentication failed");
- authStrategy.authFailed(host, authState.getAuthScheme(), context);
+ clearCache(host, context);
authState.reset();
authState.setState(AuthProtocolState.FAILURE);
return false;
@@ -150,7 +214,7 @@ public class HttpAuthenticator {
}
}
}
- final Queue<AuthOption> authOptions = authStrategy.select(challenges, host, response, context);
+ final Queue<AuthOption> authOptions = authStrategy.select(challengeType, host, challengeMap, context);
if (authOptions != null && !authOptions.isEmpty()) {
if (this.log.isDebugEnabled()) {
this.log.debug("Selected authentication options: " + authOptions);
@@ -180,7 +244,7 @@ public class HttpAuthenticator {
case FAILURE:
return;
case SUCCESS:
- ensureAuthScheme(authScheme);
+ Asserts.notNull(authScheme, "AuthScheme");
if (authScheme.isConnectionBased()) {
return;
}
@@ -209,7 +273,7 @@ public class HttpAuthenticator {
}
return;
} else {
- ensureAuthScheme(authScheme);
+ Asserts.notNull(authScheme, "AuthScheme");
}
}
if (authScheme != null) {
@@ -224,8 +288,35 @@ public class HttpAuthenticator {
}
}
- private void ensureAuthScheme(final AuthScheme authScheme) {
- Asserts.notNull(authScheme, "Auth scheme");
+ private boolean isCachable(final AuthScheme authScheme) {
+ final String schemeName = authScheme.getSchemeName();
+ return schemeName.equalsIgnoreCase(AuthSchemes.BASIC) ||
+ schemeName.equalsIgnoreCase(AuthSchemes.DIGEST);
+ }
+
+ private void updateCache(final HttpHost host, final AuthScheme authScheme, final HttpContext context) {
+ if (isCachable(authScheme)) {
+ final HttpClientContext clientContext = HttpClientContext.adapt(context);
+ final AuthCache authCache = clientContext.getAuthCache();
+ if (authCache != null) {
+ if (this.log.isDebugEnabled()) {
+ this.log.debug("Caching '" + authScheme.getSchemeName() + "' auth scheme for " + host);
+ }
+ authCache.put(host, authScheme);
+ }
+ }
+ }
+
+ private void clearCache(final HttpHost host, final HttpContext context) {
+
+ final HttpClientContext clientContext = HttpClientContext.adapt(context);
+ final AuthCache authCache = clientContext.getAuthCache();
+ if (authCache != null) {
+ if (this.log.isDebugEnabled()) {
+ this.log.debug("Clearing cached auth scheme for " + host);
+ }
+ authCache.remove(host);
+ }
}
private Header doAuth(
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/KerberosScheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/KerberosScheme.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/KerberosScheme.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/KerberosScheme.java Sat Jul 4 13:42:40 2015
@@ -26,13 +26,8 @@
*/
package org.apache.http.impl.auth;
-import org.apache.http.Header;
-import org.apache.http.HttpRequest;
import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.Credentials;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.util.Args;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.Oid;
@@ -66,59 +61,11 @@ public class KerberosScheme extends GGSS
return "Kerberos";
}
- /**
- * Produces KERBEROS authorization Header based on token created by
- * processChallenge.
- *
- * @param credentials not used by the KERBEROS scheme.
- * @param request The request being authenticated
- *
- * @throws AuthenticationException if authentication string cannot
- * be generated due to an authentication failure
- *
- * @return KERBEROS authentication Header
- */
- @Override
- public Header authenticate(
- final Credentials credentials,
- final HttpRequest request,
- final HttpContext context) throws AuthenticationException {
- return super.authenticate(credentials, request, context);
- }
-
@Override
protected byte[] generateToken(final byte[] input, final String authServer, final Credentials credentials) throws GSSException {
return generateGSSToken(input, new Oid(KERBEROS_OID), authServer, credentials);
}
- /**
- * There are no valid parameters for KERBEROS authentication so this
- * method always returns {@code null}.
- *
- * @return {@code null}
- */
- @Override
- public String getParameter(final String name) {
- Args.notNull(name, "Parameter name");
- return null;
- }
-
- /**
- * The concept of an authentication realm is not supported by the Negotiate
- * authentication scheme. Always returns {@code null}.
- *
- * @return {@code null}
- */
- @Override
- public String getRealm() {
- return null;
- }
-
- /**
- * Returns {@code true}. KERBEROS authentication scheme is connection based.
- *
- * @return {@code true}.
- */
@Override
public boolean isConnectionBased() {
return true;
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NTLMScheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NTLMScheme.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NTLMScheme.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NTLMScheme.java Sat Jul 4 13:42:40 2015
@@ -30,7 +30,9 @@ import org.apache.http.Header;
import org.apache.http.HttpRequest;
import org.apache.http.annotation.NotThreadSafe;
import org.apache.http.auth.AUTH;
+import org.apache.http.auth.AuthChallenge;
import org.apache.http.auth.AuthenticationException;
+import org.apache.http.auth.ChallengeType;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.InvalidCredentialsException;
import org.apache.http.auth.MalformedChallengeException;
@@ -47,7 +49,7 @@ import org.apache.http.util.CharArrayBuf
* @since 4.0
*/
@NotThreadSafe
-public class NTLMScheme extends AuthSchemeBase {
+public class NTLMScheme extends NonStandardAuthScheme {
enum State {
UNINITIATED,
@@ -61,14 +63,12 @@ public class NTLMScheme extends AuthSche
private final NTLMEngine engine;
private State state;
- private String challenge;
public NTLMScheme(final NTLMEngine engine) {
super();
Args.notNull(engine, "NTLM engine");
this.engine = engine;
this.state = State.UNINITIATED;
- this.challenge = null;
}
/**
@@ -84,28 +84,17 @@ public class NTLMScheme extends AuthSche
}
@Override
- public String getParameter(final String name) {
- // String parameters not supported
- return null;
- }
-
- @Override
- public String getRealm() {
- // NTLM does not support the concept of an authentication realm
- return null;
- }
-
- @Override
public boolean isConnectionBased() {
return true;
}
@Override
- protected void parseChallenge(
- final CharArrayBuffer buffer,
- final int beginIndex, final int endIndex) throws MalformedChallengeException {
- this.challenge = buffer.substringTrimmed(beginIndex, endIndex);
- if (this.challenge.isEmpty()) {
+ public void processChallenge(
+ final ChallengeType challengeType, final AuthChallenge authChallenge) throws MalformedChallengeException {
+ Args.notNull(challengeType, "ChallengeType");
+ Args.notNull(authChallenge, "AuthChallenge");
+ final String value = authChallenge.getValue();
+ if (value == null || value.isEmpty()) {
if (this.state == State.UNINITIATED) {
this.state = State.CHALLENGE_RECEIVED;
} else {
@@ -126,7 +115,7 @@ public class NTLMScheme extends AuthSche
final Credentials credentials,
final HttpRequest request,
final HttpContext context) throws AuthenticationException {
- NTCredentials ntcredentials = null;
+ final NTCredentials ntcredentials;
try {
ntcredentials = (NTCredentials) credentials;
} catch (final ClassCastException e) {
@@ -134,7 +123,7 @@ public class NTLMScheme extends AuthSche
"Credentials cannot be used for NTLM authentication: "
+ credentials.getClass().getName());
}
- String response = null;
+ final String response;
if (this.state == State.FAILED) {
throw new AuthenticationException("NTLM authentication failed");
} else if (this.state == State.CHALLENGE_RECEIVED) {
@@ -148,7 +137,7 @@ public class NTLMScheme extends AuthSche
ntcredentials.getPassword(),
ntcredentials.getNetbiosDomain(),
ntcredentials.getWorkstation(),
- this.challenge);
+ getChallenge());
this.state = State.MSG_TYPE3_GENERATED;
} else {
throw new AuthenticationException("Unexpected state: " + this.state);
Copied: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NonStandardAuthScheme.java (from r1687909, httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/ProxyAuthenticationStrategy.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NonStandardAuthScheme.java?p2=httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NonStandardAuthScheme.java&p1=httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/ProxyAuthenticationStrategy.java&r1=1687909&r2=1689155&rev=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/ProxyAuthenticationStrategy.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NonStandardAuthScheme.java Sat Jul 4 13:42:40 2015
@@ -24,34 +24,47 @@
* <http://www.apache.org/>.
*
*/
+package org.apache.http.impl.auth;
-package org.apache.http.impl.client;
+import org.apache.http.auth.AuthChallenge;
+import org.apache.http.auth.AuthScheme;
+import org.apache.http.auth.ChallengeType;
+import org.apache.http.auth.MalformedChallengeException;
-import java.util.Collection;
+public abstract class NonStandardAuthScheme implements AuthScheme {
-import org.apache.http.HttpStatus;
-import org.apache.http.annotation.Immutable;
-import org.apache.http.auth.AUTH;
-import org.apache.http.client.config.RequestConfig;
-
-/**
- * Default {@link org.apache.http.client.AuthenticationStrategy} implementation
- * for proxy host authentication.
- *
- * @since 4.2
- */
-@Immutable
-public class ProxyAuthenticationStrategy extends AuthenticationStrategyImpl {
+ private ChallengeType challengeType;
+ private String challenge;
+
+ public boolean isProxy() {
+ return this.challengeType != null && this.challengeType == ChallengeType.PROXY;
+ }
- public static final ProxyAuthenticationStrategy INSTANCE = new ProxyAuthenticationStrategy();
+ protected void update(final ChallengeType challengeType, final AuthChallenge authChallenge) throws MalformedChallengeException{
+ if (authChallenge.getValue() == null) {
+ throw new MalformedChallengeException("Missing auth challenge");
+ }
+ this.challengeType = challengeType;
+ this.challenge = authChallenge.getValue();
+ }
- public ProxyAuthenticationStrategy() {
- super(HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED, AUTH.PROXY_AUTH);
+ protected String getChallenge() {
+ return this.challenge;
+ }
+
+ @Override
+ public String getParameter(final String name) {
+ return null;
+ }
+
+ @Override
+ public String getRealm() {
+ return null;
}
@Override
- Collection<String> getPreferredAuthSchemes(final RequestConfig config) {
- return config.getProxyPreferredAuthSchemes();
+ public String toString() {
+ return getSchemeName() + "(" + this.challengeType + ") " + this.challenge;
}
}
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NonStandardAuthScheme.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NonStandardAuthScheme.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/NonStandardAuthScheme.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoScheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoScheme.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoScheme.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/SPNegoScheme.java Sat Jul 4 13:42:40 2015
@@ -26,13 +26,8 @@
*/
package org.apache.http.impl.auth;
-import org.apache.http.Header;
-import org.apache.http.HttpRequest;
import org.apache.http.annotation.NotThreadSafe;
-import org.apache.http.auth.AuthenticationException;
import org.apache.http.auth.Credentials;
-import org.apache.http.protocol.HttpContext;
-import org.apache.http.util.Args;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.Oid;
@@ -67,59 +62,11 @@ public class SPNegoScheme extends GGSSch
return "Negotiate";
}
- /**
- * Produces SPNEGO authorization Header based on token created by
- * processChallenge.
- *
- * @param credentials not used by the SPNEGO scheme.
- * @param request The request being authenticated
- *
- * @throws AuthenticationException if authentication string cannot
- * be generated due to an authentication failure
- *
- * @return SPNEGO authentication Header
- */
- @Override
- public Header authenticate(
- final Credentials credentials,
- final HttpRequest request,
- final HttpContext context) throws AuthenticationException {
- return super.authenticate(credentials, request, context);
- }
-
@Override
protected byte[] generateToken(final byte[] input, final String authServer, final Credentials credentials) throws GSSException {
return generateGSSToken(input, new Oid(SPNEGO_OID), authServer, credentials);
}
- /**
- * There are no valid parameters for SPNEGO authentication so this
- * method always returns {@code null}.
- *
- * @return {@code null}
- */
- @Override
- public String getParameter(final String name) {
- Args.notNull(name, "Parameter name");
- return null;
- }
-
- /**
- * The concept of an authentication realm is not supported by the Negotiate
- * authentication scheme. Always returns {@code null}.
- *
- * @return {@code null}
- */
- @Override
- public String getRealm() {
- return null;
- }
-
- /**
- * Returns {@code true}. SPNEGO authentication scheme is connection based.
- *
- * @return {@code true}.
- */
@Override
public boolean isConnectionBased() {
return true;
Added: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/StandardAuthScheme.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/StandardAuthScheme.java?rev=1689155&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/StandardAuthScheme.java (added)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/StandardAuthScheme.java Sat Jul 4 13:42:40 2015
@@ -0,0 +1,111 @@
+/*
+ * ====================================================================
+ * 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.auth;
+
+import java.io.Serializable;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.http.NameValuePair;
+import org.apache.http.annotation.NotThreadSafe;
+import org.apache.http.auth.AuthChallenge;
+import org.apache.http.auth.AuthScheme;
+import org.apache.http.auth.ChallengeType;
+import org.apache.http.auth.MalformedChallengeException;
+
+/**
+ * Abstract authentication scheme class that lays foundation for standard HTTP authentication schemes and
+ * provides capabilities common to all authentication schemes defined in the HTTP specification.
+ *
+ * @since 4.0
+ */
+@NotThreadSafe
+public abstract class StandardAuthScheme implements AuthScheme, Serializable {
+
+ private static final long serialVersionUID = -2845454858205884623L;
+
+ private final Map<String, String> paramMap;
+ private ChallengeType challengeType;
+
+ /**
+ * @since 4.3
+ */
+ public StandardAuthScheme() {
+ super();
+ this.paramMap = new LinkedHashMap<>();
+ }
+
+ protected void update(final ChallengeType challengeType, final AuthChallenge authChallenge) throws MalformedChallengeException {
+ final List<NameValuePair> params = authChallenge.getParams();
+ this.challengeType = challengeType;
+ if (params != null) {
+ for (NameValuePair param: params) {
+ this.paramMap.put(param.getName().toLowerCase(Locale.ROOT), param.getValue());
+ }
+ }
+ }
+
+ @Override
+ public String getRealm() {
+ return getParameter("realm");
+ }
+
+ protected Map<String, String> getParameters() {
+ return this.paramMap;
+ }
+
+ /**
+ * Returns authentication parameter with the given name, if available.
+ *
+ * @param name The name of the parameter to be returned
+ *
+ * @return the parameter with the given name
+ */
+ @Override
+ public String getParameter(final String name) {
+ if (name == null) {
+ return null;
+ }
+ return this.paramMap.get(name.toLowerCase(Locale.ROOT));
+ }
+
+ /**
+ * Returns {@code true} if authenticating against a proxy, {@code false}
+ * otherwise.
+ */
+ public boolean isProxy() {
+ return this.challengeType != null && this.challengeType == ChallengeType.PROXY;
+ }
+
+ @Override
+ public String toString() {
+ return getSchemeName() + "(" + this.challengeType + ") " + this.paramMap;
+ }
+
+}
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/StandardAuthScheme.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/StandardAuthScheme.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/auth/StandardAuthScheme.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Copied: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java (from r1687909, httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AuthenticationStrategyImpl.java)
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java?p2=httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java&p1=httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AuthenticationStrategyImpl.java&r1=1687909&r2=1689155&rev=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/AuthenticationStrategyImpl.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java Sat Jul 4 13:42:40 2015
@@ -30,7 +30,6 @@ package org.apache.http.impl.client;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
@@ -39,34 +38,37 @@ import java.util.Queue;
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.AuthChallenge;
import org.apache.http.auth.AuthOption;
import org.apache.http.auth.AuthScheme;
import org.apache.http.auth.AuthSchemeProvider;
import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.ChallengeType;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.CredentialsProvider;
import org.apache.http.auth.MalformedChallengeException;
-import org.apache.http.client.AuthCache;
import org.apache.http.client.AuthenticationStrategy;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Lookup;
-import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.Args;
-import org.apache.http.util.CharArrayBuffer;
+/**
+ * Default implementation of {@link AuthenticationStrategy}
+ *
+ * @since 5.0
+ */
@Immutable
-abstract class AuthenticationStrategyImpl implements AuthenticationStrategy {
+public class DefaultAuthenticationStrategy implements AuthenticationStrategy {
private final Log log = LogFactory.getLog(getClass());
+ public static final DefaultAuthenticationStrategy INSTANCE = new DefaultAuthenticationStrategy();
+
private static final List<String> DEFAULT_SCHEME_PRIORITY =
Collections.unmodifiableList(Arrays.asList(
AuthSchemes.SPNEGO,
@@ -75,82 +77,15 @@ abstract class AuthenticationStrategyImp
AuthSchemes.DIGEST,
AuthSchemes.BASIC));
- private final int challengeCode;
- private final String headerName;
-
- /**
- * @param challengeCode for example SC_PROXY_AUTHENTICATION_REQUIRED or SC_UNAUTHORIZED
- * @param headerName for example "Proxy-Authenticate" or "WWW-Authenticate"
- */
- AuthenticationStrategyImpl(final int challengeCode, final String headerName) {
- super();
- this.challengeCode = challengeCode;
- this.headerName = headerName;
- }
-
- @Override
- public boolean isAuthenticationRequested(
- final HttpHost authhost,
- final HttpResponse response,
- final HttpContext context) {
- Args.notNull(response, "HTTP response");
- final int status = response.getStatusLine().getStatusCode();
- return status == this.challengeCode;
- }
-
- /**
- * Generates a map of challenge auth-scheme => Header entries.
- *
- * @return map: key=lower-cased auth-scheme name, value=Header that contains the challenge
- */
- @Override
- public Map<String, Header> getChallenges(
- final HttpHost authhost,
- final HttpResponse response,
- final HttpContext context) throws MalformedChallengeException {
- Args.notNull(response, "HTTP response");
- final Header[] headers = response.getHeaders(this.headerName);
- final Map<String, Header> map = new HashMap<>(headers.length);
- for (final Header header : headers) {
- final CharArrayBuffer buffer;
- int pos;
- if (header instanceof FormattedHeader) {
- buffer = ((FormattedHeader) header).getBuffer();
- pos = ((FormattedHeader) header).getValuePos();
- } else {
- final 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++;
- }
- final int beginIndex = pos;
- while (pos < buffer.length() && !HTTP.isWhitespace(buffer.charAt(pos))) {
- pos++;
- }
- final int endIndex = pos;
- final String s = buffer.substring(beginIndex, endIndex);
- map.put(s.toLowerCase(Locale.ROOT), header);
- }
- return map;
- }
-
- abstract Collection<String> getPreferredAuthSchemes(RequestConfig config);
-
@Override
public Queue<AuthOption> select(
- final Map<String, Header> challenges,
+ final ChallengeType challengeType,
final HttpHost authhost,
- final HttpResponse response,
+ final Map<String, AuthChallenge> challenges,
final HttpContext context) throws MalformedChallengeException {
+ Args.notNull(challengeType, "ChallengeType");
Args.notNull(challenges, "Map of auth challenges");
Args.notNull(authhost, "Host");
- Args.notNull(response, "HTTP response");
Args.notNull(context, "HTTP context");
final HttpClientContext clientContext = HttpClientContext.adapt(context);
@@ -166,7 +101,8 @@ abstract class AuthenticationStrategyImp
return options;
}
final RequestConfig config = clientContext.getRequestConfig();
- Collection<String> authPrefs = getPreferredAuthSchemes(config);
+ Collection<String> authPrefs = challengeType == ChallengeType.TARGET ?
+ config.getTargetPreferredAuthSchemes() : config.getProxyPreferredAuthSchemes();
if (authPrefs == null) {
authPrefs = DEFAULT_SCHEME_PRIORITY;
}
@@ -175,7 +111,7 @@ abstract class AuthenticationStrategyImp
}
for (final String id: authPrefs) {
- final Header challenge = challenges.get(id.toLowerCase(Locale.ROOT));
+ final AuthChallenge challenge = challenges.get(id.toLowerCase(Locale.ROOT));
if (challenge != null) {
final AuthSchemeProvider authSchemeProvider = registry.lookup(id);
if (authSchemeProvider == null) {
@@ -186,7 +122,7 @@ abstract class AuthenticationStrategyImp
continue;
}
final AuthScheme authScheme = authSchemeProvider.create(context);
- authScheme.processChallenge(challenge);
+ authScheme.processChallenge(challengeType, challenge);
final AuthScope authScope = new AuthScope(
authhost.getHostName(),
@@ -208,53 +144,4 @@ abstract class AuthenticationStrategyImp
return options;
}
- @Override
- public void authSucceeded(
- final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) {
- Args.notNull(authhost, "Host");
- Args.notNull(authScheme, "Auth scheme");
- Args.notNull(context, "HTTP context");
-
- final HttpClientContext clientContext = HttpClientContext.adapt(context);
-
- if (isCachable(authScheme)) {
- AuthCache authCache = clientContext.getAuthCache();
- if (authCache == null) {
- authCache = new BasicAuthCache();
- clientContext.setAuthCache(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;
- }
- final String schemeName = authScheme.getSchemeName();
- return schemeName.equalsIgnoreCase(AuthSchemes.BASIC) ||
- schemeName.equalsIgnoreCase(AuthSchemes.DIGEST);
- }
-
- @Override
- public void authFailed(
- final HttpHost authhost, final AuthScheme authScheme, final HttpContext context) {
- Args.notNull(authhost, "Host");
- Args.notNull(context, "HTTP context");
-
- final HttpClientContext clientContext = HttpClientContext.adapt(context);
-
- final AuthCache authCache = clientContext.getAuthCache();
- if (authCache != null) {
- if (this.log.isDebugEnabled()) {
- this.log.debug("Clearing cached auth scheme for " + authhost);
- }
- authCache.remove(authhost);
- }
- }
-
}
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultAuthenticationStrategy.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpClientBuilder.java Sat Jul 4 13:42:40 2015
@@ -949,11 +949,11 @@ public class HttpClientBuilder {
}
AuthenticationStrategy targetAuthStrategyCopy = this.targetAuthStrategy;
if (targetAuthStrategyCopy == null) {
- targetAuthStrategyCopy = TargetAuthenticationStrategy.INSTANCE;
+ targetAuthStrategyCopy = DefaultAuthenticationStrategy.INSTANCE;
}
AuthenticationStrategy proxyAuthStrategyCopy = this.proxyAuthStrategy;
if (proxyAuthStrategyCopy == null) {
- proxyAuthStrategyCopy = ProxyAuthenticationStrategy.INSTANCE;
+ proxyAuthStrategyCopy = DefaultAuthenticationStrategy.INSTANCE;
}
UserTokenHandler userTokenHandlerCopy = this.userTokenHandler;
if (userTokenHandlerCopy == null) {
Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/ProxyClient.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/ProxyClient.java?rev=1689155&r1=1689154&r2=1689155&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/ProxyClient.java (original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/ProxyClient.java Sat Jul 4 13:42:40 2015
@@ -41,7 +41,9 @@ import org.apache.http.auth.AUTH;
import org.apache.http.auth.AuthSchemeProvider;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.AuthState;
+import org.apache.http.auth.ChallengeType;
import org.apache.http.auth.Credentials;
+import org.apache.http.client.AuthenticationStrategy;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.protocol.HttpClientContext;
@@ -86,7 +88,7 @@ public class ProxyClient {
private final RequestConfig requestConfig;
private final HttpProcessor httpProcessor;
private final HttpRequestExecutor requestExec;
- private final ProxyAuthenticationStrategy proxyAuthStrategy;
+ private final AuthenticationStrategy proxyAuthStrategy;
private final HttpAuthenticator authenticator;
private final AuthState proxyAuthState;
private final Lookup<AuthSchemeProvider> authSchemeRegistry;
@@ -106,7 +108,7 @@ public class ProxyClient {
this.httpProcessor = new ImmutableHttpProcessor(
new RequestTargetHost(), new RequestClientConnControl(), new RequestUserAgent());
this.requestExec = new HttpRequestExecutor();
- this.proxyAuthStrategy = new ProxyAuthenticationStrategy();
+ this.proxyAuthStrategy = new DefaultAuthenticationStrategy();
this.authenticator = new HttpAuthenticator();
this.proxyAuthState = new AuthState();
this.authSchemeRegistry = RegistryBuilder.<AuthSchemeProvider>create()
@@ -184,9 +186,8 @@ public class ProxyClient {
throw new HttpException("Unexpected response to CONNECT request: " +
response.getStatusLine());
}
- if (this.authenticator.isAuthenticationRequested(proxy, response,
- this.proxyAuthStrategy, this.proxyAuthState, context)) {
- if (this.authenticator.handleAuthChallenge(proxy, response,
+ if (this.authenticator.updateAuthState(proxy, ChallengeType.PROXY, response, this.proxyAuthState, context)) {
+ if (this.authenticator.handleAuthChallenge(proxy, ChallengeType.PROXY, response,
this.proxyAuthStrategy, this.proxyAuthState, context)) {
// Retry request
if (this.reuseStrategy.keepAlive(response, context)) {