Index: java/org/apache/commons/httpclient/HttpMethod.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethod.java,v
retrieving revision 1.34
diff -u -r1.34 HttpMethod.java
--- java/org/apache/commons/httpclient/HttpMethod.java 22 Feb 2004 18:08:45 -0000 1.34
+++ java/org/apache/commons/httpclient/HttpMethod.java 18 Mar 2004 21:11:09 -0000
@@ -34,6 +34,7 @@
import java.io.IOException;
import java.io.InputStream;
+import org.apache.commons.httpclient.auth.AuthState;
import org.apache.commons.httpclient.params.*;
@@ -211,6 +212,13 @@
void removeRequestHeader(String headerName);
/**
+ * Removes the given request header.
+ *
+ * @param header the header
+ */
+ void removeRequestHeader(Header header);
+
+ /**
* Returns true if the HTTP method should automatically follow HTTP redirects
* (status code 302, etc.), false otherwise.
*
@@ -531,5 +539,23 @@
* @param handler the methodRetryHandler to use when this method executed
*/
public void setMethodRetryHandler(MethodRetryHandler handler);
+
+ /**
+ * Returns the target host {@link AuthState authentication state}
+ *
+ * @return host authentication state
+ *
+ * @since 3.0
+ */
+ public AuthState getHostAuthState();
+
+ /**
+ * Returns the proxy {@link AuthState authentication state}
+ *
+ * @return host authentication state
+ *
+ * @since 3.0
+ */
+ public AuthState getProxyAuthState();
}
Index: java/org/apache/commons/httpclient/HttpMethodBase.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java,v
retrieving revision 1.201
diff -u -r1.201 HttpMethodBase.java
--- java/org/apache/commons/httpclient/HttpMethodBase.java 9 Mar 2004 14:01:02 -0000 1.201
+++ java/org/apache/commons/httpclient/HttpMethodBase.java 18 Mar 2004 21:11:15 -0000
@@ -36,6 +36,7 @@
import java.io.IOException;
import java.io.InputStream;
+import org.apache.commons.httpclient.auth.AuthState;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.cookie.CookieSpec;
import org.apache.commons.httpclient.cookie.MalformedCookieException;
@@ -139,6 +140,12 @@
/** HTTP protocol parameters. */
private HttpMethodParams params = new HttpMethodParams();
+ /** Host authentication state */
+ private AuthState hostAuthState = new AuthState();
+
+ /** Proxy authentication state */
+ private AuthState proxyAuthState = new AuthState();
+
/** True if this method has already been executed. */
private boolean used = false;
@@ -998,6 +1005,8 @@
responseBody = null;
recoverableExceptionCount = 0;
connectionCloseForced = false;
+ hostAuthState.invalidate();
+ proxyAuthState.invalidate();
}
/**
@@ -1040,6 +1049,18 @@
}
}
+
+ /**
+ * Removes the given request header.
+ *
+ * @param header the header
+ */
+ public void removeRequestHeader(final Header header) {
+ if (header == null) {
+ return;
+ }
+ getRequestHeaderGroup().removeHeader(header);
+ }
// ---------------------------------------------------------------- Queries
@@ -2039,27 +2060,27 @@
}
/**
- * @deprecated no longer used
- *
* Returns proxy authentication realm, if it has been used during authentication process.
* Otherwise returns null.
*
* @return proxy authentication realm
+ *
+ * @deprecated use #getProxyAuthState()
*/
public String getProxyAuthenticationRealm() {
- return null;
+ return this.proxyAuthState.getRealm();
}
/**
- * @deprecated no longer used
- *
* Returns authentication realm, if it has been used during authentication process.
* Otherwise returns null.
*
* @return authentication realm
+ *
+ * @deprecated use #getHostAuthState()
*/
public String getAuthenticationRealm() {
- return null;
+ return this.hostAuthState.getRealm();
}
/**
@@ -2241,4 +2262,25 @@
this.responseStream = responseStream;
}
+ /**
+ * Returns the target host {@link AuthState authentication state}
+ *
+ * @return host authentication state
+ *
+ * @since 3.0
+ */
+ public AuthState getHostAuthState() {
+ return this.hostAuthState;
+ }
+
+ /**
+ * Returns the proxy {@link AuthState authentication state}
+ *
+ * @return host authentication state
+ *
+ * @since 3.0
+ */
+ public AuthState getProxyAuthState() {
+ return this.proxyAuthState;
+ }
}
Index: java/org/apache/commons/httpclient/HttpMethodDirector.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodDirector.java,v
retrieving revision 1.18
diff -u -r1.18 HttpMethodDirector.java
--- java/org/apache/commons/httpclient/HttpMethodDirector.java 22 Feb 2004 18:08:46 -0000 1.18
+++ java/org/apache/commons/httpclient/HttpMethodDirector.java 18 Mar 2004 21:11:17 -0000
@@ -32,13 +32,13 @@
package org.apache.commons.httpclient;
import java.io.IOException;
-import java.util.Collection;
-import java.util.Iterator;
import java.util.Map;
+import org.apache.commons.httpclient.auth.AuthChallengeException;
import org.apache.commons.httpclient.auth.AuthChallengeParser;
-import org.apache.commons.httpclient.auth.AuthPolicy;
+import org.apache.commons.httpclient.auth.AuthChallengeProcessor;
import org.apache.commons.httpclient.auth.AuthScheme;
+import org.apache.commons.httpclient.auth.AuthState;
import org.apache.commons.httpclient.auth.AuthenticationException;
import org.apache.commons.httpclient.auth.CredentialsProvider;
import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
@@ -93,20 +93,11 @@
private static final int AUTH_NOT_REQUIRED = Integer.MAX_VALUE;
/** Actual state of authentication process */
- private int authState = AUTH_UNINITIATED;
+ private int authProcess = AUTH_UNINITIATED;
- /** Actual authentication scheme */
- private AuthScheme authScheme = null;
+ /** Authentication processor */
+ private AuthChallengeProcessor authProcessor = null;
- /** Whether preemtive authentication is attempted */
- private boolean authPreemptive = false;
-
- /** Actual proxy authentication scheme */
- private AuthScheme proxyAuthScheme = null;
-
- /** Whether preemtive proxy authentication is attempted */
- private boolean proxyAuthPreemptive = false;
-
public HttpMethodDirector(
final HttpConnectionManager connectionManager,
final HostConfiguration hostConfiguration,
@@ -118,6 +109,7 @@
this.hostConfiguration = hostConfiguration;
this.params = params;
this.state = state;
+ this.authProcessor = new AuthChallengeProcessor(this.params);
}
@@ -128,9 +120,7 @@
* @throws HttpException
*/
public void executeMethod(final HttpMethod method) throws IOException, HttpException {
-
- if (method == null)
- {
+ if (method == null) {
throw new IllegalArgumentException("Method may not be null");
}
method.getParams().setDefaults(this.params);
@@ -161,12 +151,10 @@
|| this.state.isAuthenticationPreemptive())
{
LOG.debug("Preemptively sending default basic credentials");
- this.authState = AUTH_PREEMPTIVE;
- this.authScheme = AuthPolicy.getAuthScheme("basic");
- this.authPreemptive = true;
+ this.authProcess = AUTH_PREEMPTIVE;
+ method.getHostAuthState().setPreemptive();
if (this.conn.isProxied()) {
- this.proxyAuthPreemptive = true;
- this.proxyAuthScheme = AuthPolicy.getAuthScheme("basic");
+ method.getProxyAuthState().setPreemptive();
}
}
}
@@ -188,7 +176,7 @@
retry = true;
}
} else {
- this.authState = AUTH_NOT_REQUIRED;
+ this.authProcess = AUTH_NOT_REQUIRED;
}
if (!retry) {
break;
@@ -237,14 +225,33 @@
}
}
+
+ private boolean cleanAuthHeaders(final HttpMethod method, final String name) {
+ Header[] authheaders = method.getRequestHeaders(name);
+ boolean clean = true;
+ for (int i = 0; i < authheaders.length; i++) {
+ Header authheader = authheaders[i];
+ if (authheader.isAutogenerated()) {
+ method.removeRequestHeader(authheader);
+ } else {
+ clean = false;
+ }
+ }
+ return clean;
+ }
+
private void authenticateHost(final HttpMethod method) throws AuthenticationException {
// Clean up existing authentication headers
- method.removeRequestHeader(WWW_AUTH_RESP);
- if ((this.authScheme != null)
- && ((this.authState == AUTH_WWW_REQUIRED)
- || (!this.authScheme.isConnectionBased())))
- {
+ if (!cleanAuthHeaders(method, WWW_AUTH_RESP)) {
+ // User defined authentication header(s) present
+ return;
+ }
+ AuthScheme authscheme = method.getHostAuthState().getAuthScheme();
+ if (authscheme == null) {
+ return;
+ }
+ if ((this.authProcess == AUTH_WWW_REQUIRED) || (!authscheme.isConnectionBased())) {
String host = conn.getVirtualHost();
if (host == null) {
host = conn.getHost();
@@ -252,14 +259,14 @@
int port = conn.getPort();
HttpAuthRealm realm = new HttpAuthRealm(
host, port,
- this.authScheme.getRealm(),
- this.authScheme.getSchemeName());
+ authscheme.getRealm(),
+ authscheme.getSchemeName());
if (LOG.isDebugEnabled()) {
LOG.debug("Authenticating with " + realm);
}
Credentials credentials = this.state.getCredentials(realm);
if (credentials != null) {
- String authstring = this.authScheme.authenticate(credentials, method);
+ String authstring = authscheme.authenticate(credentials, method);
if (authstring != null) {
method.addRequestHeader(new Header(WWW_AUTH_RESP, authstring, true));
}
@@ -272,21 +279,26 @@
private void authenticateProxy(final HttpMethod method) throws AuthenticationException {
// Clean up existing authentication headers
- method.removeRequestHeader(PROXY_AUTH_RESP);
- if ((this.proxyAuthScheme != null)
- && ((this.authState == AUTH_PROXY_REQUIRED)
- || (!this.proxyAuthScheme.isConnectionBased())))
- {
+ // Clean up existing authentication headers
+ if (!cleanAuthHeaders(method, PROXY_AUTH_RESP)) {
+ // User defined authentication header(s) present
+ return;
+ }
+ AuthScheme authscheme = method.getProxyAuthState().getAuthScheme();
+ if (authscheme == null) {
+ return;
+ }
+ if ((this.authProcess == AUTH_PROXY_REQUIRED) || (!authscheme.isConnectionBased())) {
HttpAuthRealm realm = new HttpAuthRealm(
conn.getProxyHost(), conn.getProxyPort(),
- this.proxyAuthScheme.getRealm(),
- this.proxyAuthScheme.getSchemeName());
+ authscheme.getRealm(),
+ authscheme.getSchemeName());
if (LOG.isDebugEnabled()) {
LOG.debug("Authenticating with " + realm);
}
Credentials credentials = this.state.getProxyCredentials(realm);
if (credentials != null) {
- String authstring = this.proxyAuthScheme.authenticate(credentials, method);
+ String authstring = authscheme.authenticate(credentials, method);
if (authstring != null) {
method.addRequestHeader(new Header(PROXY_AUTH_RESP, authstring, true));
}
@@ -416,7 +428,7 @@
retry = true;
}
} else {
- this.authState = AUTH_NOT_REQUIRED;
+ this.authProcess = AUTH_NOT_REQUIRED;
}
if (!retry) {
break;
@@ -467,6 +479,8 @@
this.connectMethod.getResponseHeaderGroup(),
this.connectMethod.getResponseBodyAsStream()
);
+ method.getProxyAuthState().setAuthScheme(
+ this.connectMethod.getProxyAuthState().getAuthScheme());
this.connectMethod = null;
} else {
releaseConnection = true;
@@ -537,7 +551,7 @@
}
//And finally invalidate the actual authentication scheme
- this.authScheme = null;
+ method.getHostAuthState().invalidate();
return true;
}
@@ -574,21 +588,24 @@
private boolean processWWWAuthChallenge(final HttpMethod method)
throws MalformedChallengeException, AuthenticationException
{
- if (this.authPreemptive) {
- this.authScheme = null;
- this.authPreemptive = false;
+ AuthState authstate = method.getHostAuthState();
+ if (authstate.isPreemptive()) {
+ authstate.invalidate();
}
Map challenges = AuthChallengeParser.parseChallenges(
method.getResponseHeaders(WWW_AUTH_CHALLENGE));
if (challenges.isEmpty()) {
return false;
}
- if (this.authScheme != null) {
- processChallenge(this.authScheme, challenges);
- } else {
- this.authScheme = processChallenge(challenges);
+ AuthScheme authscheme = null;
+ try {
+ authscheme = this.authProcessor.processChallenge(authstate, challenges);
+ } catch (AuthChallengeException e) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn(e.getMessage());
+ }
}
- if (this.authScheme == null) {
+ if (authscheme == null) {
return false;
}
String host = conn.getVirtualHost();
@@ -598,13 +615,13 @@
int port = conn.getPort();
HttpAuthRealm realm = new HttpAuthRealm(
host, port,
- this.authScheme.getRealm(),
- this.authScheme.getSchemeName());
+ authscheme.getRealm(),
+ authscheme.getSchemeName());
- if ((this.authState == AUTH_WWW_REQUIRED)
- && (this.authScheme.isComplete())) {
+ if ((this.authProcess == AUTH_WWW_REQUIRED) && (authscheme.isComplete())) {
// Already tried and failed
- Credentials credentials = promptForCredentials(method.getParams(), realm);
+ Credentials credentials = promptForCredentials(
+ authscheme, method.getParams(), realm);
if (credentials == null) {
if (LOG.isInfoEnabled()) {
LOG.info("Failure authenticating with " + realm);
@@ -614,11 +631,12 @@
return true;
}
} else {
- this.authState = AUTH_WWW_REQUIRED;
+ this.authProcess = AUTH_WWW_REQUIRED;
Credentials credentials = this.state.getCredentials(realm);
if (credentials == null) {
- credentials = promptForCredentials(method.getParams(), realm);
+ credentials = promptForCredentials(
+ authscheme, method.getParams(), realm);
}
if (credentials == null) {
if (LOG.isInfoEnabled()) {
@@ -634,32 +652,35 @@
private boolean processProxyAuthChallenge(final HttpMethod method)
throws MalformedChallengeException, AuthenticationException
{
- if (this.proxyAuthPreemptive) {
- this.proxyAuthScheme = null;
- this.proxyAuthPreemptive = false;
+ AuthState authstate = method.getProxyAuthState();
+ if (authstate.isPreemptive()) {
+ authstate.invalidate();
}
Map proxyChallenges = AuthChallengeParser.parseChallenges(
method.getResponseHeaders(PROXY_AUTH_CHALLENGE));
if (proxyChallenges.isEmpty()) {
return false;
}
- if (this.proxyAuthScheme != null) {
- processChallenge(this.proxyAuthScheme, proxyChallenges);
- } else {
- this.proxyAuthScheme = processChallenge(proxyChallenges);
+ AuthScheme authscheme = null;
+ try {
+ authscheme = this.authProcessor.processChallenge(authstate, proxyChallenges);
+ } catch (AuthChallengeException e) {
+ if (LOG.isWarnEnabled()) {
+ LOG.warn(e.getMessage());
+ }
}
- if (this.proxyAuthScheme == null) {
+ if (authscheme == null) {
return false;
}
HttpAuthRealm realm = new HttpAuthRealm(
conn.getProxyHost(), conn.getProxyPort(),
- this.proxyAuthScheme.getRealm(),
- this.proxyAuthScheme.getSchemeName());
+ authscheme.getRealm(),
+ authscheme.getSchemeName());
- if ((this.authState == AUTH_PROXY_REQUIRED)
- && (this.proxyAuthScheme.isComplete())) {
+ if ((this.authProcess == AUTH_PROXY_REQUIRED) && (authscheme.isComplete())) {
// Already tried and failed
- Credentials credentials = promptForProxyCredentials(method.getParams(), realm);
+ Credentials credentials = promptForProxyCredentials(
+ authscheme, method.getParams(), realm);
if (credentials == null) {
if (LOG.isInfoEnabled()) {
LOG.info("Failure authenticating with " + realm);
@@ -669,11 +690,12 @@
return true;
}
} else {
- this.authState = AUTH_PROXY_REQUIRED;
+ this.authProcess = AUTH_PROXY_REQUIRED;
Credentials credentials = this.state.getProxyCredentials(realm);
if (credentials == null) {
- credentials = promptForProxyCredentials(method.getParams(), realm);
+ credentials = promptForProxyCredentials(
+ authscheme, method.getParams(), realm);
}
if (credentials == null) {
if (LOG.isInfoEnabled()) {
@@ -686,71 +708,6 @@
}
}
- private void processChallenge(final AuthScheme authscheme, final Map challenges)
- throws MalformedChallengeException, AuthenticationException
- {
- String id = authscheme.getSchemeName();
- if (LOG.isDebugEnabled()) {
- LOG.debug("Using present authentication scheme: " + id);
- }
- String challenge = (String) challenges.get(id.toLowerCase());
- if (challenge == null) {
- throw new AuthenticationException(id +
- " authorization challenge expected, but not found");
- }
- authscheme.processChallenge(challenge);
- }
-
- private AuthScheme processChallenge(final Map challenges)
- throws MalformedChallengeException, AuthenticationException {
-
- Collection authPrefs = (Collection) this.params.getParameter(
- AuthPolicy.AUTH_SCHEME_PRIORITY);
- if (authPrefs == null || authPrefs.isEmpty()) {
- authPrefs = AuthPolicy.getDefaultAuthPrefs();
- }
-
- AuthScheme authscheme = null;
- String challenge = null;
- if (LOG.isDebugEnabled()) {
- LOG.debug("Supported authentication schemes in the order of preference: "
- + authPrefs);
- }
- Iterator item = authPrefs.iterator();
- while (item.hasNext()) {
- String id = (String) item.next();
- challenge = (String) challenges.get(id.toLowerCase());
- if (challenge != null) {
- if (LOG.isInfoEnabled()) {
- LOG.info(id + " authentication scheme selected");
- }
- authscheme = AuthPolicy.getAuthScheme(id);
- if (authscheme == null) {
- throw new AuthenticationException("Requested authorization scheme " +
- id + " is not supported");
- }
- // Looks like we got something
- break;
- } else {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Challenge for " + id + " authentication scheme not available");
- // Try again
- }
- }
- }
- if (authscheme == null) {
- // If none selected, something is wrong, warn and leave
- if (LOG.isWarnEnabled()) {
- LOG.warn("None of the following challenges can be responsed to: "
- + challenges);
- }
- } else {
- // Process the challenge
- authscheme.processChallenge(challenge);
- }
- return authscheme;
- }
-
/**
* Tests if the {@link HttpMethod method} requires a redirect to another location.
*
@@ -802,6 +759,7 @@
}
private Credentials promptForCredentials(
+ final AuthScheme authScheme,
final HttpParams params,
final HttpAuthRealm realm)
{
@@ -811,7 +769,7 @@
if (credProvider != null) {
try {
creds = credProvider.getCredentials(
- this.authScheme, realm.getHost(), realm.getPort(), false);
+ authScheme, realm.getHost(), realm.getPort(), false);
} catch (CredentialsNotAvailableException e) {
LOG.warn(e.getMessage());
}
@@ -826,6 +784,7 @@
}
private Credentials promptForProxyCredentials(
+ final AuthScheme authScheme,
final HttpParams params,
final HttpAuthRealm realm)
{
@@ -835,7 +794,7 @@
if (credProvider != null) {
try {
creds = credProvider.getCredentials(
- this.proxyAuthScheme, realm.getHost(), realm.getPort(), true);
+ authScheme, realm.getHost(), realm.getPort(), true);
} catch (CredentialsNotAvailableException e) {
LOG.warn(e.getMessage());
}
@@ -875,33 +834,5 @@
*/
public HttpParams getParams() {
return this.params;
- }
-
- /**
- * Returns the authentication scheme used to authenticate with the
- * target host.
- *
- * @return the authentication scheme used to authenticate with the
- * target host. Null is returned if target host authentication
- * was not required.
- *
- * @since 2.1
- */
- public AuthScheme getAuthScheme() {
- return authScheme;
- }
-
- /**
- * Returns the authentication scheme used to authenticate with the
- * proxy host.
- *
- * @return the authentication scheme used to authenticate with the
- * proxy host. Null is returned if proxy authentication was not
- * required.
- *
- * @since 2.1
- */
- public AuthScheme getProxyAuthScheme() {
- return proxyAuthScheme;
}
}
Index: java/org/apache/commons/httpclient/auth/AuthChallengeException.java
===================================================================
RCS file: java/org/apache/commons/httpclient/auth/AuthChallengeException.java
diff -N java/org/apache/commons/httpclient/auth/AuthChallengeException.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/auth/AuthChallengeException.java 18 Mar 2004 21:11:18 -0000
@@ -0,0 +1,70 @@
+/*
+ * $Header: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthenticationException.java,v 1.4 2004/02/22 18:08:47 olegk Exp $
+ * $Revision: 1.4 $
+ * $Date: 2004/02/22 18:08:47 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-2004 The Apache Software Foundation
+ *
+ * Licensed 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
+ * .
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.commons.httpclient.auth;
+
+/**
+ * Signals a failure processing authentication challenge
+ *
+ * @author Oleg Kalnichevski
+ *
+ * @since 3.0
+ */
+public class AuthChallengeException extends AuthenticationException {
+
+ /**
+ * Creates a new AuthChallengeException with a null detail message.
+ */
+ public AuthChallengeException() {
+ super();
+ }
+
+ /**
+ * Creates a new AuthChallengeException with the specified message.
+ *
+ * @param message the exception detail message
+ */
+ public AuthChallengeException(String message) {
+ super(message);
+ }
+
+ /**
+ * Creates a new AuthChallengeException with the specified detail message and cause.
+ *
+ * @param message the exception detail message
+ * @param cause the Throwable that caused this exception, or null
+ * if the cause is unavailable, unknown, or not a Throwable
+ */
+ public AuthChallengeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
Index: java/org/apache/commons/httpclient/auth/AuthChallengeProcessor.java
===================================================================
RCS file: java/org/apache/commons/httpclient/auth/AuthChallengeProcessor.java
diff -N java/org/apache/commons/httpclient/auth/AuthChallengeProcessor.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/auth/AuthChallengeProcessor.java 18 Mar 2004 21:11:18 -0000
@@ -0,0 +1,165 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2002-2004 The Apache Software Foundation
+ *
+ * Licensed 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
+ * .
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.commons.httpclient.auth;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.commons.httpclient.params.HttpParams;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This class provides utility methods for processing HTTP www and proxy authentication
+ * challenges.
+ *
+ * @author Oleg Kalnichevski
+ *
+ * @since 3.0
+ */
+public final class AuthChallengeProcessor {
+
+ private static final Log LOG = LogFactory.getLog(AuthChallengeProcessor.class);
+
+ private HttpParams params = null;
+
+ /**
+ * Creates an authentication challenge processor with the given {@link HttpParams HTTP
+ * parameters}
+ *
+ * @param params the {@link HttpParams HTTP parameters} used by this processor
+ */
+ public AuthChallengeProcessor(final HttpParams params) {
+ super();
+ if (params == null) {
+ throw new IllegalArgumentException("Parameter collection may not be null");
+ }
+ this.params = params;
+ }
+
+ /**
+ * Determines the preferred {@link AuthScheme authentication scheme} that can be used
+ * to respond to the given collection of challenges.
+ *
+ * @param challenges the collection of authentication challenges
+ *
+ * @return the preferred {@link AuthScheme authentication scheme}
+ *
+ * @throws AuthChallengeException if the preferred authentication scheme
+ * cannot be determined or is not supported
+ */
+ public AuthScheme selectAuthScheme(final Map challenges) throws AuthChallengeException {
+ if (challenges == null) {
+ throw new IllegalArgumentException("Challenge map may not be null");
+ }
+ Collection authPrefs = (Collection) this.params.getParameter(
+ AuthPolicy.AUTH_SCHEME_PRIORITY);
+ if (authPrefs == null || authPrefs.isEmpty()) {
+ authPrefs = AuthPolicy.getDefaultAuthPrefs();
+ }
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Supported authentication schemes in the order of preference: "
+ + authPrefs);
+ }
+ AuthScheme authscheme = null;
+ String challenge = null;
+ Iterator item = authPrefs.iterator();
+ while (item.hasNext()) {
+ String id = (String) item.next();
+ challenge = (String) challenges.get(id.toLowerCase());
+ if (challenge != null) {
+ if (LOG.isInfoEnabled()) {
+ LOG.info(id + " authentication scheme selected");
+ }
+ try {
+ authscheme = AuthPolicy.getAuthScheme(id);
+ } catch (IllegalStateException e) {
+ throw new AuthChallengeException(e.getMessage());
+ }
+ break;
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Challenge for " + id + " authentication scheme not available");
+ // Try again
+ }
+ }
+ }
+ if (authscheme == null) {
+ // If none selected, something is wrong
+ throw new AuthChallengeException(
+ "Unable to respond to any of these challenges: "
+ + challenges);
+ }
+ return authscheme;
+ }
+
+ /**
+ * Processes the given collection of challenges and updates the
+ * {@link AuthState state} of the authentication process.
+ *
+ * @param challenges the collection of authentication challenges
+ *
+ * @return the {@link AuthScheme authentication scheme} used to
+ * process the challenge
+ *
+ * @throws AuthChallengeException if authentication challenges cannot be
+ * successfully processed or the preferred authentication scheme cannot
+ * be determined
+ */
+ public AuthScheme processChallenge(final AuthState state, final Map challenges)
+ throws MalformedChallengeException, AuthenticationException
+ {
+ if (state == null) {
+ throw new IllegalArgumentException("Authentication state may not be null");
+ }
+ if (challenges == null) {
+ throw new IllegalArgumentException("Challenge map may not be null");
+ }
+ if (state.getAuthScheme() == null) {
+ // Authentication not attempted before
+ state.setAuthScheme(selectAuthScheme(challenges));
+ }
+ AuthScheme authscheme = state.getAuthScheme();
+ String id = authscheme.getSchemeName();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Using authentication scheme: " + id);
+ }
+ String challenge = (String) challenges.get(id.toLowerCase());
+ if (challenge == null) {
+ throw new AuthenticationException(id +
+ " authorization challenge expected, but not found");
+ }
+ authscheme.processChallenge(challenge);
+ return authscheme;
+ }
+}
Index: java/org/apache/commons/httpclient/auth/AuthState.java
===================================================================
RCS file: java/org/apache/commons/httpclient/auth/AuthState.java
diff -N java/org/apache/commons/httpclient/auth/AuthState.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ java/org/apache/commons/httpclient/auth/AuthState.java 18 Mar 2004 21:11:18 -0000
@@ -0,0 +1,117 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed 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
+ * .
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.commons.httpclient.auth;
+
+/**
+ * This class provides detailed information about the state of the
+ * authentication process.
+ *
+ * @author Oleg Kalnichevski
+ * @since 3.0
+ */
+public class AuthState {
+
+ /** Actual authentication scheme */
+ private AuthScheme authScheme = null;
+
+ /** Whether preemtive authentication is attempted */
+ private boolean preemptive = false;
+
+ /**
+ * Default constructor.
+ *
+ */
+ public AuthState() {
+ super();
+ }
+
+ /**
+ * Preemptively assigns Basic authentication scheme.
+ */
+ public void setPreemptive() {
+ if (this.authScheme != null) {
+ throw new IllegalStateException("Authentication state already initialized");
+ }
+ this.authScheme = AuthPolicy.getAuthScheme("basic");
+ this.preemptive = true;
+ }
+
+ /**
+ * Invalidates the authentication state by resetting its parameters.
+ */
+ public void invalidate() {
+ this.authScheme = null;
+ this.preemptive = false;
+ }
+
+ /**
+ * Tests if preemptive authentication is used.
+ *
+ * @return true if using the default Basic {@link AuthScheme
+ * authentication scheme}, false otherwise.
+ */
+ public boolean isPreemptive() {
+ return this.preemptive;
+ }
+
+ /**
+ * Assigns the given {@link AuthScheme authentication scheme}.
+ *
+ * @param authScheme the {@link AuthScheme authentication scheme}
+ */
+ public void setAuthScheme(final AuthScheme authScheme) {
+ this.authScheme = authScheme;
+ this.preemptive = false;
+ }
+
+ /**
+ * Returns the {@link AuthScheme authentication scheme}.
+ *
+ * @return {@link AuthScheme authentication scheme}
+ */
+ public AuthScheme getAuthScheme() {
+ return authScheme;
+ }
+
+ /**
+ * Returns the authentication realm.
+ *
+ * @return the name of the authentication realm
+ */
+ public String getRealm() {
+ if (this.authScheme != null) {
+ return this.authScheme.getRealm();
+ } else {
+ return null;
+ }
+ }
+}
Index: test/org/apache/commons/httpclient/TestChallengeParser.java
===================================================================
RCS file: test/org/apache/commons/httpclient/TestChallengeParser.java
diff -N test/org/apache/commons/httpclient/TestChallengeParser.java
--- test/org/apache/commons/httpclient/TestChallengeParser.java 22 Feb 2004 18:08:49 -0000 1.3
+++ /dev/null 1 Jan 1970 00:00:00 -0000
@@ -1,80 +0,0 @@
-/*
- * ====================================================================
- *
- * Copyright 1999-2004 The Apache Software Foundation
- *
- * Licensed 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
- * .
- *
- * [Additional notices, if required by prior licensing conditions]
- *
- */
-
-package org.apache.commons.httpclient;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-import java.util.Map;
-import org.apache.commons.httpclient.auth.AuthChallengeParser;
-import org.apache.commons.httpclient.auth.MalformedChallengeException;
-
-/**
- * Unit tests for {@link AuthChallengeParser}.
- *
- * @author Oleg Kalnichevski
- */
-public class TestChallengeParser extends TestCase {
-
- // ------------------------------------------------------------ Constructor
- public TestChallengeParser(String testName) {
- super(testName);
- }
-
- // ------------------------------------------------------------------- Main
- public static void main(String args[]) {
- String[] testCaseName = { TestChallengeParser.class.getName() };
- junit.textui.TestRunner.main(testCaseName);
- }
-
- // ------------------------------------------------------- TestCase Methods
-
- public static Test suite() {
- return new TestSuite(TestChallengeParser.class);
- }
-
-
- public void testParsingChallenge() {
- String challenge =
- "Basic realm=\"realm1\", test, test1 = stuff, test2 = \"stuff, stuff\", test3=\"crap";
- String scheme = null;
- Map elements = null;
- try {
- scheme = AuthChallengeParser.extractScheme(challenge);
- elements = AuthChallengeParser.extractParams(challenge);
- } catch (MalformedChallengeException e) {
- fail("Unexpected exception: " + e.toString());
- }
- assertEquals("basic", scheme);
- assertEquals("realm1", elements.get("realm"));
- assertEquals(null, elements.get("test"));
- assertEquals("stuff", elements.get("test1"));
- assertEquals("stuff, stuff", elements.get("test2"));
- assertEquals("\"crap", elements.get("test3"));
- }
-}
Index: test/org/apache/commons/httpclient/TestExceptions.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestExceptions.java,v
retrieving revision 1.3
diff -u -r1.3 TestExceptions.java
--- test/org/apache/commons/httpclient/TestExceptions.java 22 Feb 2004 18:08:49 -0000 1.3
+++ test/org/apache/commons/httpclient/TestExceptions.java 18 Mar 2004 21:11:19 -0000
@@ -34,6 +34,8 @@
import java.io.PrintWriter;
import java.io.StringWriter;
+import org.apache.commons.httpclient.auth.*;
+
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
Index: test/org/apache/commons/httpclient/TestNoHost.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestNoHost.java,v
retrieving revision 1.32
diff -u -r1.32 TestNoHost.java
--- test/org/apache/commons/httpclient/TestNoHost.java 27 Feb 2004 19:01:33 -0000 1.32
+++ test/org/apache/commons/httpclient/TestNoHost.java 18 Mar 2004 21:11:20 -0000
@@ -35,6 +35,8 @@
import junit.framework.TestSuite;
import org.apache.commons.httpclient.auth.TestBasicAuth;
+import org.apache.commons.httpclient.auth.TestChallengeParser;
+import org.apache.commons.httpclient.auth.TestChallengeProcessor;
/**
* Tests that don't require any external host.
@@ -61,6 +63,7 @@
suite.addTest(TestParameterParser.suite());
suite.addTest(TestHeaderElement.suite());
suite.addTest(TestChallengeParser.suite());
+ suite.addTest(TestChallengeProcessor.suite());
suite.addTest(TestAuthenticator.suite());
suite.addTest(TestBasicAuth.suite());
suite.addTest(TestHttpUrlMethod.suite());
Index: test/org/apache/commons/httpclient/auth/TestBasicAuth.java
===================================================================
RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/auth/TestBasicAuth.java,v
retrieving revision 1.1
diff -u -r1.1 TestBasicAuth.java
--- test/org/apache/commons/httpclient/auth/TestBasicAuth.java 27 Feb 2004 19:04:32 -0000 1.1
+++ test/org/apache/commons/httpclient/auth/TestBasicAuth.java 18 Mar 2004 21:11:21 -0000
@@ -216,6 +216,10 @@
this.client.executeMethod(httpget);
assertNotNull(httpget.getStatusLine());
assertEquals(HttpStatus.SC_UNAUTHORIZED, httpget.getStatusLine().getStatusCode());
+ AuthState authstate = httpget.getHostAuthState();
+ assertNotNull(authstate.getAuthScheme());
+ assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
+ assertEquals("test", authstate.getRealm());
} finally {
httpget.releaseConnection();
}
@@ -262,6 +266,10 @@
String expected = "Basic " + EncodingUtil.getAsciiString(
Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
assertEquals(expected, auth.getValue());
+ AuthState authstate = httpget.getHostAuthState();
+ assertNotNull(authstate.getAuthScheme());
+ assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
+ assertEquals("test", authstate.getRealm());
}
public void testBasicAuthentication() throws Exception {
@@ -286,6 +294,10 @@
String expected = "Basic " + EncodingUtil.getAsciiString(
Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
assertEquals(expected, auth.getValue());
+ AuthState authstate = httpget.getHostAuthState();
+ assertNotNull(authstate.getAuthScheme());
+ assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
+ assertEquals("test", authstate.getRealm());
}
public void testBasicAuthenticationWithInvalidCredentials() throws Exception {
@@ -305,6 +317,10 @@
}
assertNotNull(httpget.getStatusLine());
assertEquals(HttpStatus.SC_FORBIDDEN, httpget.getStatusLine().getStatusCode());
+ AuthState authstate = httpget.getHostAuthState();
+ assertNotNull(authstate.getAuthScheme());
+ assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
+ assertEquals("test", authstate.getRealm());
}
public void testBasicAuthenticationWithMutlipleRealms() throws Exception {
@@ -335,6 +351,10 @@
String expected = "Basic " + EncodingUtil.getAsciiString(
Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
assertEquals(expected, auth.getValue());
+ AuthState authstate = httpget.getHostAuthState();
+ assertNotNull(authstate.getAuthScheme());
+ assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
+ assertEquals("test", authstate.getRealm());
}
{
this.server.setHttpService(new BasicAuthService2());
@@ -351,6 +371,10 @@
String expected = "Basic " + EncodingUtil.getAsciiString(
Base64.encodeBase64(EncodingUtil.getAsciiBytes("test2:test2")));
assertEquals(expected, auth.getValue());
+ AuthState authstate = httpget.getHostAuthState();
+ assertNotNull(authstate.getAuthScheme());
+ assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
+ assertEquals("test2", authstate.getRealm());
}
}
@@ -373,6 +397,11 @@
String expected = "Basic " + EncodingUtil.getAsciiString(
Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
assertEquals(expected, auth.getValue());
+ AuthState authstate = httpget.getHostAuthState();
+ assertNotNull(authstate.getAuthScheme());
+ assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
+ assertNull(authstate.getRealm());
+ assertTrue(authstate.isPreemptive());
}
public void testBasicAuthenticationCaseInsensitivity() throws Exception {
@@ -397,5 +426,21 @@
String expected = "Basic " + EncodingUtil.getAsciiString(
Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
assertEquals(expected, auth.getValue());
+ }
+
+
+ public void testCustomAuthorizationHeader() throws Exception {
+ String authResponse = "Basic " + EncodingUtil.getAsciiString(
+ Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
+ this.server.setHttpService(new BasicAuthService());
+ GetMethod httpget = new GetMethod("/test/");
+ httpget.addRequestHeader(new Header("Authorization", authResponse));
+ try {
+ this.client.executeMethod(httpget);
+ } finally {
+ httpget.releaseConnection();
+ }
+ assertNotNull(httpget.getStatusLine());
+ assertEquals(HttpStatus.SC_OK, httpget.getStatusLine().getStatusCode());
}
}
Index: test/org/apache/commons/httpclient/auth/TestChallengeParser.java
===================================================================
RCS file: test/org/apache/commons/httpclient/auth/TestChallengeParser.java
diff -N test/org/apache/commons/httpclient/auth/TestChallengeParser.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/org/apache/commons/httpclient/auth/TestChallengeParser.java 18 Mar 2004 21:11:21 -0000
@@ -0,0 +1,83 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ * ====================================================================
+ *
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed 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
+ * .
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.commons.httpclient.auth;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import java.util.Map;
+import org.apache.commons.httpclient.auth.AuthChallengeParser;
+import org.apache.commons.httpclient.auth.MalformedChallengeException;
+
+/**
+ * Unit tests for {@link AuthChallengeParser}.
+ *
+ * @author Oleg Kalnichevski
+ */
+public class TestChallengeParser extends TestCase {
+
+ // ------------------------------------------------------------ Constructor
+ public TestChallengeParser(String testName) {
+ super(testName);
+ }
+
+ // ------------------------------------------------------------------- Main
+ public static void main(String args[]) {
+ String[] testCaseName = { TestChallengeParser.class.getName() };
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+ // ------------------------------------------------------- TestCase Methods
+
+ public static Test suite() {
+ return new TestSuite(TestChallengeParser.class);
+ }
+
+
+ public void testParsingChallenge() {
+ String challenge =
+ "Basic realm=\"realm1\", test, test1 = stuff, test2 = \"stuff, stuff\", test3=\"crap";
+ String scheme = null;
+ Map elements = null;
+ try {
+ scheme = AuthChallengeParser.extractScheme(challenge);
+ elements = AuthChallengeParser.extractParams(challenge);
+ } catch (MalformedChallengeException e) {
+ fail("Unexpected exception: " + e.toString());
+ }
+ assertEquals("basic", scheme);
+ assertEquals("realm1", elements.get("realm"));
+ assertEquals(null, elements.get("test"));
+ assertEquals("stuff", elements.get("test1"));
+ assertEquals("stuff, stuff", elements.get("test2"));
+ assertEquals("\"crap", elements.get("test3"));
+ }
+}
Index: test/org/apache/commons/httpclient/auth/TestChallengeProcessor.java
===================================================================
RCS file: test/org/apache/commons/httpclient/auth/TestChallengeProcessor.java
diff -N test/org/apache/commons/httpclient/auth/TestChallengeProcessor.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test/org/apache/commons/httpclient/auth/TestChallengeProcessor.java 18 Mar 2004 21:11:22 -0000
@@ -0,0 +1,173 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ * ====================================================================
+ *
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed 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
+ * .
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.apache.commons.httpclient.auth;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.commons.httpclient.params.DefaultHttpParams;
+import org.apache.commons.httpclient.params.HttpParams;
+
+/**
+ * Unit tests for {@link testParsingChallenge}.
+ *
+ * @author Oleg Kalnichevski
+ */
+public class TestChallengeProcessor extends TestCase {
+
+ // ------------------------------------------------------------ Constructor
+ public TestChallengeProcessor(String testName) {
+ super(testName);
+ }
+
+ // ------------------------------------------------------------------- Main
+ public static void main(String args[]) {
+ String[] testCaseName = { TestChallengeProcessor.class.getName() };
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+ // ------------------------------------------------------- TestCase Methods
+
+ public static Test suite() {
+ return new TestSuite(TestChallengeProcessor.class);
+ }
+
+
+ public void testChallengeSelection() throws Exception {
+ List authPrefs = new ArrayList(3);
+ authPrefs.add(AuthPolicy.NTLM);
+ authPrefs.add(AuthPolicy.DIGEST);
+ authPrefs.add(AuthPolicy.BASIC);
+ HttpParams httpparams = new DefaultHttpParams();
+ httpparams.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
+
+ AuthChallengeProcessor processor = new AuthChallengeProcessor(httpparams);
+
+ Map map = new HashMap();
+ map.put("unknown", "unknown realm=\"whatever\"");
+ map.put("basic", "basic realm=\"whatever\"");
+
+ AuthScheme authscheme = processor.selectAuthScheme(map);
+ assertTrue(authscheme instanceof BasicScheme);
+ }
+
+
+ public void testInvalidChallenge() throws Exception {
+ List authPrefs = new ArrayList(3);
+ authPrefs.add("unsupported1");
+ authPrefs.add("unsupported2");
+ HttpParams httpparams = new DefaultHttpParams();
+ httpparams.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
+
+ AuthChallengeProcessor processor = new AuthChallengeProcessor(httpparams);
+
+ Map map = new HashMap();
+ map.put("unsupported1", "unsupported1 realm=\"whatever\"");
+ map.put("unsupported2", "unsupported2 realm=\"whatever\"");
+ try {
+ AuthScheme authscheme = processor.selectAuthScheme(map);
+ fail("AuthChallengeException should have been thrown");
+ } catch (AuthChallengeException e) {
+ //ignore
+ }
+ }
+
+
+ public void testUnsupportedChallenge() throws Exception {
+ List authPrefs = new ArrayList(3);
+ authPrefs.add(AuthPolicy.NTLM);
+ authPrefs.add(AuthPolicy.BASIC);
+ authPrefs.add(AuthPolicy.DIGEST);
+ HttpParams httpparams = new DefaultHttpParams();
+ httpparams.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
+
+ AuthChallengeProcessor processor = new AuthChallengeProcessor(httpparams);
+
+ Map map = new HashMap();
+ map.put("unsupported1", "unsupported1 realm=\"whatever\"");
+ map.put("unsupported2", "unsupported2 realm=\"whatever\"");
+
+ try {
+ AuthScheme authscheme = processor.selectAuthScheme(map);
+ fail("AuthChallengeException should have been thrown");
+ } catch (AuthChallengeException e) {
+ //expected
+ }
+ }
+
+ public void testChallengeProcessing() throws Exception {
+ HttpParams httpparams = new DefaultHttpParams();
+ AuthChallengeProcessor processor = new AuthChallengeProcessor(httpparams);
+
+ Map map = new HashMap();
+ map.put("basic", "basic realm=\"whatever\", param=\"value\"");
+
+ AuthState authstate = new AuthState();
+
+ AuthScheme authscheme = processor.processChallenge(authstate, map);
+ assertTrue(authscheme instanceof BasicScheme);
+ assertEquals("whatever", authscheme.getRealm());
+ assertEquals(authscheme, authstate.getAuthScheme());
+ assertEquals("value", authscheme.getParameter("param"));
+ }
+
+ public void testInvalidChallengeProcessing() throws Exception {
+ HttpParams httpparams = new DefaultHttpParams();
+ AuthChallengeProcessor processor = new AuthChallengeProcessor(httpparams);
+
+ Map map = new HashMap();
+ map.put("basic", "basic realm=\"whatever\", param=\"value\"");
+
+ AuthState authstate = new AuthState();
+
+ AuthScheme authscheme = processor.processChallenge(authstate, map);
+ assertTrue(authscheme instanceof BasicScheme);
+ assertEquals("whatever", authscheme.getRealm());
+ assertEquals(authscheme, authstate.getAuthScheme());
+ assertEquals("value", authscheme.getParameter("param"));
+
+ Map map2 = new HashMap();
+ map2.put("ntlm", "NTLM");
+ try {
+ // Basic authentication scheme expected
+ authscheme = processor.processChallenge(authstate, map2);
+ fail("AuthenticationException should have been thrown");
+ } catch (AuthenticationException e) {
+ //expected
+ }
+ }
+}