You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ol...@apache.org on 2003/12/10 22:04:13 UTC

cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/server ProxyAuthRequestHandler.java

olegk       2003/12/10 13:04:13

  Modified:    httpclient/src/java/org/apache/commons/httpclient
                        ConnectMethod.java HttpMethodBase.java
                        HttpMethodDirector.java
               httpclient/src/java/org/apache/commons/httpclient/auth
                        AuthChallengeParser.java AuthScheme.java
                        AuthSchemeBase.java BasicScheme.java
                        DigestScheme.java HttpAuthenticator.java
                        NTLMScheme.java RFC2617Scheme.java
               httpclient/src/test/org/apache/commons/httpclient
                        TestAuthenticator.java
               httpclient/src/test/org/apache/commons/httpclient/server
                        ProxyAuthRequestHandler.java
  Log:
  Changelog:
  
  * Another attempt at fixing NTLM proxy + basic host authentication (R: #24352)
  
  * Plug-in mechanism for authentication modules
  
  * AuthModule interface implementing authentication modules can now be
  instantiated using default (parameter-less) constructor
  
  * Authentication modules can now retain limited state information (the state is
  retained within the lifetime of the method director)
  
  * Authentication scheme selection routine can be easily parameterized
  
  * Yet another massive refactoring of HttpMethodDirector
  
  Contributed by Oleg Kalnichevski
  Reviewed By Michael Becke
  
  Revision  Changes    Path
  1.23      +4 -5      jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ConnectMethod.java
  
  Index: ConnectMethod.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ConnectMethod.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- ConnectMethod.java	10 Nov 2003 23:19:49 -0000	1.22
  +++ ConnectMethod.java	10 Dec 2003 21:04:13 -0000	1.23
  @@ -171,7 +171,6 @@
               + "HttpConnection)");
           addUserAgentRequestHeader(state, conn);
           addHostRequestHeader(state, conn);
  -        addProxyAuthorizationRequestHeader(state, conn);
           addProxyConnectionHeader(state, conn);
       }
   
  
  
  
  1.191     +7 -95     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java
  
  Index: HttpMethodBase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java,v
  retrieving revision 1.190
  retrieving revision 1.191
  diff -u -r1.190 -r1.191
  --- HttpMethodBase.java	13 Nov 2003 22:24:46 -0000	1.190
  +++ HttpMethodBase.java	10 Dec 2003 21:04:13 -0000	1.191
  @@ -68,12 +68,10 @@
   import java.io.IOException;
   import java.io.InputStream;
   
  -import org.apache.commons.httpclient.auth.AuthScheme;
  -import org.apache.commons.httpclient.auth.HttpAuthenticator;
   import org.apache.commons.httpclient.cookie.CookiePolicy;
   import org.apache.commons.httpclient.cookie.CookieSpec;
   import org.apache.commons.httpclient.cookie.MalformedCookieException;
  -import org.apache.commons.httpclient.params.*;
  +import org.apache.commons.httpclient.params.HttpMethodParams;
   import org.apache.commons.httpclient.protocol.Protocol;
   import org.apache.commons.httpclient.util.EncodingUtil;
   import org.apache.commons.logging.Log;
  @@ -146,12 +144,6 @@
       /** Response trailer headers, if any. */
       private HeaderGroup responseTrailerHeaders = new HeaderGroup();
   
  -    /** Actual authentication realm */
  -    private String realm = null;
  -
  -    /** Actual proxy authentication realm */
  -    private String proxyRealm = null;
  -
       /** Path of the HTTP method. */
       private String path = null;
   
  @@ -1027,8 +1019,6 @@
           path = null;
           followRedirects = false;
           doAuthentication = true;
  -        realm = null;
  -        proxyRealm = null;
           queryString = null;
           getRequestHeaderGroup().clear();
           getResponseHeaderGroup().clear();
  @@ -1096,45 +1086,6 @@
   
   
       /**
  -     * Generates <tt>Authorization</tt> request header if needed, as long as no
  -     * <tt>Authorization</tt> request header already exists.
  -     *
  -     * @param state the {@link HttpState state} information associated with this method
  -     * @param conn the {@link HttpConnection connection} used to execute
  -     *        this HTTP method
  -     *
  -     * @throws IOException if an I/O (transport) error occurs. Some transport exceptions
  -     *                     can be recovered from.
  -     * @throws HttpException  if a protocol exception occurs. Usually protocol exceptions 
  -     *                    cannot be recovered from.
  -     */
  -    protected void addAuthorizationRequestHeader(HttpState state,
  -                                                 HttpConnection conn)
  -    throws IOException, HttpException {
  -        LOG.trace("enter HttpMethodBase.addAuthorizationRequestHeader("
  -                  + "HttpState, HttpConnection)");
  -
  -        // add authorization header, if needed
  -        if (getRequestHeader(HttpAuthenticator.WWW_AUTH_RESP) == null) {
  -            Header[] challenges = getResponseHeaderGroup().getHeaders(
  -                                               HttpAuthenticator.WWW_AUTH);
  -            if (challenges.length > 0) {
  -                try {
  -                    AuthScheme authscheme = HttpAuthenticator.selectAuthScheme(challenges);
  -                    HttpAuthenticator.authenticate(authscheme, this, conn, state);
  -                } catch (HttpException e) {
  -                    // log and move on
  -                    if (LOG.isErrorEnabled()) {
  -                        LOG.error(e.getMessage(), e);
  -                    }
  -                }
  -            }
  -        }
  -    }
  -
  -
  -
  -    /**
        * Generates <tt>Cookie</tt> request headers for those {@link Cookie cookie}s
        * that match the given host, port and path.
        *
  @@ -1232,43 +1183,6 @@
       }
   
       /**
  -     * Generates <tt>Proxy-Authorization</tt> request header if needed, as long as no
  -     * <tt>Proxy-Authorization</tt> request header already exists.
  -     *
  -     * @param state the {@link HttpState state} information associated with this method
  -     * @param conn the {@link HttpConnection connection} used to execute
  -     *        this HTTP method
  -     *
  -     * @throws IOException if an I/O (transport) error occurs. Some transport exceptions
  -     *                     can be recovered from.
  -     * @throws HttpException  if a protocol exception occurs. Usually protocol exceptions 
  -     *                    cannot be recovered from.
  -     */
  -    protected void addProxyAuthorizationRequestHeader(HttpState state,
  -                                                      HttpConnection conn)
  -    throws IOException, HttpException {
  -        LOG.trace("enter HttpMethodBase.addProxyAuthorizationRequestHeader("
  -                  + "HttpState, HttpConnection)");
  -
  -        // add proxy authorization header, if needed
  -        if (getRequestHeader(HttpAuthenticator.PROXY_AUTH_RESP) == null) {
  -            Header[] challenges = getResponseHeaderGroup().getHeaders(
  -                                               HttpAuthenticator.PROXY_AUTH);
  -            if (challenges.length > 0) {
  -                try {
  -                    AuthScheme authscheme = HttpAuthenticator.selectAuthScheme(challenges);
  -                    HttpAuthenticator.authenticateProxy(authscheme, this, conn, state);
  -                } catch (HttpException e) {
  -                    // log and move on
  -                    if (LOG.isErrorEnabled()) {
  -                        LOG.error(e.getMessage(), e);
  -                    }
  -                }
  -            }
  -        }
  -    }
  -
  -    /**
        * Generates <tt>Proxy-Connection: Keep-Alive</tt> request header when 
        * communicating via a proxy server.
        *
  @@ -1326,8 +1240,6 @@
           addUserAgentRequestHeader(state, conn);
           addHostRequestHeader(state, conn);
           addCookieRequestHeader(state, conn);
  -        addAuthorizationRequestHeader(state, conn);
  -        addProxyAuthorizationRequestHeader(state, conn);
           addProxyConnectionHeader(state, conn);
       }
   
  @@ -2155,7 +2067,7 @@
        * @return proxy authentication realm
        */
       public String getProxyAuthenticationRealm() {
  -        return this.proxyRealm;
  +        return null;
       }
   
       /**
  @@ -2167,7 +2079,7 @@
        * @return authentication realm
        */
       public String getAuthenticationRealm() {
  -        return this.realm;
  +        return null;
       }
   
       /**
  
  
  
  1.11      +192 -102  jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodDirector.java
  
  Index: HttpMethodDirector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodDirector.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- HttpMethodDirector.java	19 Nov 2003 21:11:16 -0000	1.10
  +++ HttpMethodDirector.java	10 Dec 2003 21:04:13 -0000	1.11
  @@ -64,15 +64,22 @@
   package org.apache.commons.httpclient;
   
   import java.io.IOException;
  +import java.util.ArrayList;
   import java.util.HashSet;
  +import java.util.Iterator;
  +import java.util.List;
  +import java.util.Map;
   import java.util.Set;
   
  +import org.apache.commons.httpclient.auth.AuthChallengeParser;
  +import org.apache.commons.httpclient.auth.AuthPolicy;
   import org.apache.commons.httpclient.auth.AuthScheme;
   import org.apache.commons.httpclient.auth.AuthenticationException;
   import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
   import org.apache.commons.httpclient.auth.HttpAuthenticator;
   import org.apache.commons.httpclient.auth.MalformedChallengeException;
  -import org.apache.commons.httpclient.params.*;
  +import org.apache.commons.httpclient.params.HttpClientParams;
  +import org.apache.commons.httpclient.params.HttpParams;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
  @@ -107,11 +114,19 @@
       /** Proxy Realms that we tried to authenticate to */
       private Set proxyRealms = null;
   
  -    /** Actual authentication realm */
  -    private String realm = null;
  +    /** Actual authentication scheme */
  +    private AuthScheme authScheme = null;
   
  -    /** Actual proxy authentication realm */
  -    private String proxyRealm = null;
  +    /** Actual proxy authentication scheme */
  +    private AuthScheme proxyAuthScheme = null;
  +
  +    //TODO: to be parameterized
  +    private static final List AUTH_PREFERENCES = new ArrayList(3);
  +    static {
  +        AUTH_PREFERENCES.add(AuthPolicy.NTLM);
  +        AUTH_PREFERENCES.add(AuthPolicy.DIGEST);
  +        AUTH_PREFERENCES.add(AuthPolicy.BASIC);
  +    }
       
       public HttpMethodDirector(
           final HttpConnectionManager connectionManager,
  @@ -484,7 +499,12 @@
   		//invalidate the list of authentication attempts
   		this.realms.clear();
   		//remove exisitng authentication headers
  -		method.removeRequestHeader(HttpAuthenticator.WWW_AUTH_RESP); 
  +        if ((this.proxyAuthScheme != null) && (this.proxyAuthScheme.isConnectionBased())) {
  +            method.removeRequestHeader(HttpAuthenticator.PROXY_AUTH);
  +        }
  +		method.removeRequestHeader(HttpAuthenticator.WWW_AUTH_RESP);
  +        //Invalidate present authentication scheme
  +        this.authScheme = null; 
   		//update the current location with the redirect location.
   		//avoiding use of URL.getPath() and URL.getQuery() to keep
   		//jdk1.2 comliance.
  @@ -514,109 +534,179 @@
   		LOG.trace("enter HttpMethodBase.processAuthenticationResponse("
   			+ "HttpState, HttpConnection)");
   
  +        if ((this.proxyAuthScheme != null) && (this.proxyAuthScheme.isConnectionBased())) {
  +            method.removeRequestHeader(HttpAuthenticator.PROXY_AUTH);
  +        }
  +        if ((this.authScheme != null) && (this.authScheme.isConnectionBased())) {
  +            method.removeRequestHeader(HttpAuthenticator.WWW_AUTH);
  +        }
           boolean authenticated = false;
  -		int statusCode = method.getStatusCode();
  -		// handle authentication required
  -		Header[] challenges = null;
  -		Set realmsUsed = null;
  -        String host = null;
  -		switch (statusCode) {
  -			case HttpStatus.SC_UNAUTHORIZED:
  -				challenges = method.getResponseHeaders(HttpAuthenticator.WWW_AUTH);
  -				realmsUsed = realms;
  -                host = this.conn.getVirtualHost();
  -                if (host == null) {
  -                    host = this.conn.getHost();
  -                }
  -				break;
  -			case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
  -                challenges = method.getResponseHeaders(HttpAuthenticator.PROXY_AUTH);
  -				realmsUsed = proxyRealms;
  -                host = this.conn.getProxyHost();
  -				break;
  +		try {
  +            switch (method.getStatusCode()) {
  +                case HttpStatus.SC_UNAUTHORIZED:
  +                    Map challenges = AuthChallengeParser.parseChallenges(
  +                        method.getResponseHeaders(HttpAuthenticator.WWW_AUTH));
  +                    if (challenges.isEmpty()) {
  +                        return false; 
  +                    }
  +                    if (this.authScheme != null) {
  +                        processChallenge(this.authScheme, challenges);
  +                    } else {
  +                        this.authScheme = processChallenge(challenges);
  +                        if (this.authScheme == null) {
  +                            return false;
  +                        }
  +                    }
  +                    String host = this.conn.getVirtualHost();
  +                    if (host == null) {
  +                        host = this.conn.getHost();
  +                    }
  +                    if (previousAttemptFailed(this.realms, host, 
  +                        this.authScheme))  {
  +                        return false;
  +                    }
  +                    method.removeRequestHeader(HttpAuthenticator.WWW_AUTH_RESP);
  +                    authenticated = HttpAuthenticator.authenticate(
  +                        this.authScheme, method, this.conn, this.state);
  +                    break;
  +                case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
  +                    Map proxyChallenges = AuthChallengeParser.parseChallenges(
  +                        method.getResponseHeaders(HttpAuthenticator.PROXY_AUTH));
  +                    if (proxyChallenges.isEmpty()) {
  +                        return false; 
  +                    }
  +                    if (this.proxyAuthScheme != null) {
  +                        processChallenge(this.proxyAuthScheme, proxyChallenges);
  +                    } else {
  +                        this.proxyAuthScheme = processChallenge(proxyChallenges);
  +                        if (this.proxyAuthScheme == null) {
  +                            return false;
  +                        }
  +                    }
  +                    if (previousAttemptFailed(this.proxyRealms, this.conn.getProxyHost(), 
  +                        this.proxyAuthScheme)) {
  +                        return false;
  +                    }
  +                    method.removeRequestHeader(HttpAuthenticator.PROXY_AUTH_RESP);
  +                    authenticated = HttpAuthenticator.authenticateProxy(
  +                        proxyAuthScheme, method, this.conn, this.state);
  +                    break;
  +            }
  +        } catch (MalformedChallengeException e) {
  +            if (LOG.isErrorEnabled()) {
  +                LOG.error(e.getMessage(), e);
  +            }
  +            return false;
  +        } catch (CredentialsNotAvailableException e) {
  +            if (LOG.isWarnEnabled()) {
  +                LOG.warn(e.getMessage());
  +            }
  +            return false;
  +		} catch (AuthenticationException e) {
  +            if (LOG.isErrorEnabled()) {
  +                LOG.error(e.getMessage(), e);
  +            }
  +            return false;
   		}
  -		// if there was a header requesting authentication
  -		if (challenges.length > 0) {
  -			AuthScheme authscheme = null;
  -			try {
  -				authscheme = HttpAuthenticator.selectAuthScheme(challenges);
  -			} catch (MalformedChallengeException e) {
  -				if (LOG.isErrorEnabled()) {
  -					LOG.error(e.getMessage(), e);
  -				}
  -				return false;
  -			} catch (UnsupportedOperationException e) {
  -				if (LOG.isErrorEnabled()) {
  -					LOG.error(e.getMessage(), e);
  -				}
  -				return false;
  -			}
  -        
  -            StringBuffer buffer = new StringBuffer();
  -            buffer.append(host);
  -            buffer.append('#');
  -            buffer.append(authscheme.getID());
  -            String realm = buffer.toString();
  +		if (!authenticated) {
  +			// won't be able to authenticate to this challenge
  +			// without additional information
  +			LOG.debug("Credentials required to respond to authorization" + 
  +                " challenge are not available");
  +		} else {
  +            LOG.debug("Credentials required to respond to authorization" + 
  +                " challenge have been provided");
  +			// let's try it again, using the credentials
  +		}
  +		return authenticated;
  +	}
   
  -            if (realmsUsed.contains(realm)) {
  +    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 {    
  +        AuthScheme authscheme = null;
  +        String challenge = null;
  +        if (LOG.isDebugEnabled()) {
  +            LOG.debug("Supported authentication schemes in the order of preference: " 
  +                + AUTH_PREFERENCES);
  +        }
  +        Iterator item = AUTH_PREFERENCES.iterator();
  +        while (item.hasNext()) {
  +            String id = (String) item.next();
  +            challenge = (String) challenges.get(id.toLowerCase()); 
  +            if (challenge != null) {
                   if (LOG.isInfoEnabled()) {
  -                    buffer = new StringBuffer();
  -                    buffer.append("Already tried to authenticate with '");
  -                    buffer.append(authscheme.getRealm());
  -                    buffer.append("' authentication realm at ");
  -                    buffer.append(host);
  -                    buffer.append(", but still receiving: ");
  -                    buffer.append(method.getStatusLine().toString());
  -                    LOG.info(buffer.toString());
  +                    LOG.info(id + " authentication scheme selected");
  +                }
  +                authscheme = AuthPolicy.getAuthScheme(id);
  +                if (authscheme == null) {    
  +                    throw new AuthenticationException("Requested authorization scheme " +
  +                        id + " is not supported");
                   }
  -                return false;
  +                // Looks like we got something
  +                break;
               } else {
  -                realmsUsed.add(realm);
  +                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;
  +    }
   
  -            method.removeRequestHeader(HttpAuthenticator.WWW_AUTH_RESP);
  -            method.removeRequestHeader(HttpAuthenticator.PROXY_AUTH_RESP);
  -			try {
  -				//remove preemptive header and reauthenticate
  -				switch (statusCode) {
  -					case HttpStatus.SC_UNAUTHORIZED:
  -						authenticated = HttpAuthenticator.authenticate(
  -							authscheme, method, this.conn, this.state);
  -						this.realm = authscheme.getRealm();
  -						break;
  -					case HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED:
  -						authenticated = HttpAuthenticator.authenticateProxy(
  -							authscheme, method, this.conn, this.state);
  -						this.proxyRealm = authscheme.getRealm();
  -						break;
  -				}
  -            } catch (CredentialsNotAvailableException e) {
  -                if (LOG.isWarnEnabled()) {
  -                    LOG.warn(e.getMessage());
  -                }
  -                return false; // finished request
  -			} catch (AuthenticationException e) {
  -                if (LOG.isErrorEnabled()) {
  -                    LOG.error(e.getMessage(), e);
  -                }
  -                return false; // finished request
  -			}
  -			if (!authenticated) {
  -				// won't be able to authenticate to this challenge
  -				// without additional information
  -				LOG.debug("HttpMethodBase.execute(): Server demands "
  -						  + "authentication credentials, but none are "
  -						  + "available, so aborting.");
  -			} else {
  -				LOG.debug("HttpMethodBase.execute(): Server demanded "
  -						  + "authentication credentials, will try again.");
  -				// let's try it again, using the credentials
  -			}
  -		}
   
  -		return authenticated;
  -	}
  +    private boolean previousAttemptFailed(final Set realms, final String host, final AuthScheme authscheme) {
  +        // See if authentication against the given realm & host has
  +        // already been attempted
  +        StringBuffer buffer = new StringBuffer();
  +        buffer.append(host);
  +        buffer.append('#');
  +        buffer.append(authscheme.getID());
  +        String realm = buffer.toString();
  +
  +        if (realms.contains(realm)) {
  +            // Already tried. Give up
  +            if (LOG.isInfoEnabled()) {
  +                buffer = new StringBuffer();
  +                buffer.append("Attempt to authenticate with '");
  +                buffer.append(authscheme.getRealm());
  +                buffer.append("' authentication realm at ");
  +                buffer.append(host);
  +                buffer.append(" failed");
  +                LOG.info(buffer.toString());
  +            }
  +            return true;
  +        } else {
  +            realms.add(realm);
  +            return false;
  +        }
   
  +    }
       /**
        * Tests if the {@link HttpMethod method} requires a redirect to another location.
        * 
  
  
  
  1.7       +30 -3     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthChallengeParser.java
  
  Index: AuthChallengeParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthChallengeParser.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- AuthChallengeParser.java	13 Jul 2003 21:29:05 -0000	1.6
  +++ AuthChallengeParser.java	10 Dec 2003 21:04:13 -0000	1.7
  @@ -67,6 +67,7 @@
   import java.util.List;
   import java.util.Map;
   
  +import org.apache.commons.httpclient.Header;
   import org.apache.commons.httpclient.NameValuePair;
   import org.apache.commons.httpclient.util.ParameterParser;
   
  @@ -139,4 +140,30 @@
           }
           return map;
       }
  +
  +    /** 
  +     * Extracts a map of challenges ordered by authentication scheme name
  +     *
  +     * @param headers the array of authorization challenges
  +     * @return a map of authorization challenges
  +     * 
  +     * @throws MalformedChallengeException if any of challenge strings
  +     *  is malformed
  +     * 
  +     * @since 2.0beta1
  +     */
  +    public static Map parseChallenges(final Header[] headers)
  +      throws MalformedChallengeException {
  +        if (headers == null) {
  +            throw new IllegalArgumentException("Array of challenges may not be null");
  +        }
  +        String challenge = null;
  +        Map challengemap = new HashMap(headers.length); 
  +        for (int i = 0; i < headers.length; i++) {
  +            challenge = headers[i].getValue();
  +            String s = AuthChallengeParser.extractScheme(challenge);
  +            challengemap.put(s, challenge);
  +        }
  +        return challengemap;
  +   }
   }
  
  
  
  1.5       +33 -6     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthScheme.java
  
  Index: AuthScheme.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthScheme.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- AuthScheme.java	22 Apr 2003 17:00:25 -0000	1.4
  +++ AuthScheme.java	10 Dec 2003 21:04:13 -0000	1.5
  @@ -67,23 +67,31 @@
   
   /**
    * <p>
  - * This interface represents an abstract authentication scheme.
  + * This interface represents an abstract challenge-response oriented 
  + * authentication scheme.
    * </p>
    * <p>
    * An authentication scheme should be able to support the following
    * functions:
    * <ul>
  + *   <li>Parse and process the challenge sent by the targer server
  + *       in response to request for a protected resource
    *   <li>Provide its textual designation
    *   <li>Provide its parameters, if available
    *   <li>Provide the realm this authentication scheme is applicable to,
    *       if available
    *   <li>Generate authorization string for the given set of credentials,
    *       request method and URI as specificed in the HTTP request line
  + *       in response to the actual authorization challenge
    * </ul>
    * </p>
    * <p>
    * Authentication schemes may ignore method name and URI parameters
  - * if they are relevant for the given authentication mechanism
  + * if they are not relevant for the given authentication mechanism
  + * </p>
  + * <p>
  + * Authentication schemes may be stateful involving a series of 
  + * challenge-response exchanges
    * </p>
    * 
    * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
  @@ -93,6 +101,15 @@
    */
   
   public interface AuthScheme {
  +
  +    /**
  +     * Processes the given challenge token. Some authentication schemes
  +     * may involve multiple challenge-response exchanges. Such schemes must be able 
  +     * to maintain the state information when dealing with sequential challenges 
  +     * 
  +     * @param the challenge string
  +     */
  +    void processChallenge(final String challenge) throws MalformedChallengeException;
       
       /**
        * Returns textual designation of the given authentication scheme.
  @@ -136,10 +153,20 @@
        * returned value may be null.
        */
       String getID();
  +
  +    /**
  +     * Tests if the authentication scheme is provides authorization on a per
  +     * connection basis instead of usual per request basis
  +     * 
  +     * @return <tt>true</tt> if the scheme is connection based, <tt>false</tt>
  +     * if the scheme is request based.
  +     */
  +    boolean isConnectionBased();    
       
       /**
        * Produces an authorization string for the given set of {@link Credentials},
  -     * method name and URI using the given authentication scheme.
  +     * method name and URI using the given authentication scheme in response to 
  +     * the actual authorization challenge.
        * 
        * @param credentials The set of credentials to be used for athentication
        * @param method The name of the method that requires authorization. 
  
  
  
  1.4       +7 -3      jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthSchemeBase.java
  
  Index: AuthSchemeBase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthSchemeBase.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- AuthSchemeBase.java	6 Apr 2003 22:31:53 -0000	1.3
  +++ AuthSchemeBase.java	10 Dec 2003 21:04:13 -0000	1.4
  @@ -68,6 +68,7 @@
    * Abstract authentication scheme class that implements {@link AuthScheme}
    * interface and provides a default contstructor.
    * </p>
  + * @deprecated No longer used
    *
    * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
    */
  @@ -85,6 +86,9 @@
        * 
        * @throws MalformedChallengeException is thrown if the authentication challenge
        * is malformed
  +     * 
  +     * @deprecated Use parameterless constructor and {@link AuthScheme#challenge(String)} 
  +     *             method
        */
       public AuthSchemeBase(final String challenge) 
         throws MalformedChallengeException {
  
  
  
  1.8       +23 -3     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/BasicScheme.java
  
  Index: BasicScheme.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/BasicScheme.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- BasicScheme.java	14 Nov 2003 02:28:49 -0000	1.7
  +++ BasicScheme.java	10 Dec 2003 21:04:13 -0000	1.8
  @@ -91,12 +91,23 @@
       private static final Log LOG = LogFactory.getLog(BasicScheme.class);
       
       /**
  +     * Default constructor for the basic authetication scheme.
  +     * 
  +     */
  +    public BasicScheme() {
  +        super();
  +    }
  +
  +    /**
        * Constructor for the basic authetication scheme.
        * 
        * @param challenge authentication challenge
        * 
        * @throws MalformedChallengeException is thrown if the authentication challenge
        * is malformed
  +     * 
  +     * @deprecated Use parameterless constructor and {@link AuthScheme#challenge(String)} 
  +     *             method
        */
       public BasicScheme(final String challenge) throws MalformedChallengeException {
           super(challenge);
  @@ -140,6 +151,15 @@
                 + credentials.getClass().getName());
           }
           return BasicScheme.authenticate(usernamepassword);
  +    }
  +
  +    /**
  +     * Returns <tt>false</tt>. Basic authentication scheme is request based.
  +     * 
  +     * @return <tt>false</tt>.
  +     */
  +    public boolean isConnectionBased() {
  +        return false;    
       }
   
       /**
  
  
  
  1.12      +67 -5     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/DigestScheme.java
  
  Index: DigestScheme.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/DigestScheme.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- DigestScheme.java	3 Oct 2003 20:57:36 -0000	1.11
  +++ DigestScheme.java	10 Dec 2003 21:04:13 -0000	1.12
  @@ -120,6 +120,14 @@
       private String cnonce;
   
       /**
  +     * Default constructor for the digest authetication scheme.
  +     * 
  +     */
  +    public DigestScheme() {
  +        super();
  +    }
  +
  +    /**
        * Gets an ID based upon the realm and the nonce value.  This ensures that requests
        * to the same realm with different nonce values will succeed.  This differentiation
        * allows servers to request re-authentication using a fresh nonce value.
  @@ -136,12 +144,15 @@
       }
   
       /**
  -     * Constructor for the digest authentication scheme.
  +     * Constructor for the digest authetication scheme.
        * 
  -     * @param challenge The authentication challenge
  +     * @param challenge authentication challenge
        * 
        * @throws MalformedChallengeException is thrown if the authentication challenge
        * is malformed
  +     * 
  +     * @deprecated Use parameterless constructor and {@link AuthScheme#challenge(String)} 
  +     *             method
        */
       public DigestScheme(final String challenge) 
         throws MalformedChallengeException {
  @@ -177,6 +188,48 @@
           cnonce = createCnonce();   
       }
   
  +    /**
  +     * Processes the Digest challenge.
  +     *  
  +     * @param the challenge string
  +     * 
  +     * @throws MalformedChallengeException is thrown if the authentication challenge
  +     * is malformed
  +     */
  +    public void processChallenge(final String challenge) 
  +      throws MalformedChallengeException {
  +        super.processChallenge(challenge);
  +        
  +        if (getParameter("nonce") == null) {
  +            throw new MalformedChallengeException("missing nonce in challange");   
  +        }
  +        
  +        boolean unsupportedQop = false;
  +        // qop parsing
  +        String qop = getParameter("qop");
  +        if (qop != null) {
  +            StringTokenizer tok = new StringTokenizer(qop,",");
  +            while (tok.hasMoreTokens()) {
  +                String variant = tok.nextToken().trim();
  +                if (variant.equals("auth")) {
  +                    qopVariant = QOP_AUTH;
  +                    break; //that's our favourite, because auth-int is unsupported
  +                } else if (variant.equals("auth-int")) {
  +                    qopVariant = QOP_AUTH_INT;               
  +                } else {
  +                    unsupportedQop = true;
  +                    LOG.warn("Unsupported qop detected: "+ variant);   
  +                }     
  +            }
  +        }        
  +        
  +        if (unsupportedQop && (qopVariant == QOP_MISSING)) {
  +            throw new MalformedChallengeException("None of the qop methods is supported");   
  +        }
  +        
  +        cnonce = createCnonce();   
  +    }
  +
   
       /**
        * Returns textual designation of the digest authentication scheme.
  @@ -185,6 +238,15 @@
        */
       public String getSchemeName() {
           return "digest";
  +    }
  +
  +    /**
  +     * Returns <tt>false</tt>. Digest authentication scheme is request based.
  +     * 
  +     * @return <tt>false</tt>.
  +     */
  +    public boolean isConnectionBased() {
  +        return false;    
       }
   
       /**
  
  
  
  1.14      +9 -8      jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/HttpAuthenticator.java
  
  Index: HttpAuthenticator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/HttpAuthenticator.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- HttpAuthenticator.java	2 Nov 2003 12:10:28 -0000	1.13
  +++ HttpAuthenticator.java	10 Dec 2003 21:04:13 -0000	1.14
  @@ -63,12 +63,13 @@
   
   package org.apache.commons.httpclient.auth;
   
  -import java.util.Map;
   import java.util.HashMap;
  +import java.util.Map;
  +
  +import org.apache.commons.httpclient.Credentials;
   import org.apache.commons.httpclient.Header;
   import org.apache.commons.httpclient.HttpConnection;
   import org.apache.commons.httpclient.HttpMethod;
  -import org.apache.commons.httpclient.Credentials;
   import org.apache.commons.httpclient.HttpState;
   import org.apache.commons.httpclient.UsernamePasswordCredentials;
   import org.apache.commons.logging.Log;
  @@ -110,19 +111,16 @@
        */
       public static final String WWW_AUTH = "WWW-Authenticate";
   
  -
       /**
        * The www authenticate response header.
        */
       public static final String WWW_AUTH_RESP = "Authorization";
   
  -
       /**
        * The proxy authenticate challange header.
        */
       public static final String PROXY_AUTH = "Proxy-Authenticate";
   
  -
       /**
        * The proxy authenticate response header.
        */
  @@ -145,6 +143,9 @@
        *  challenge is malformed
        * @throws UnsupportedOperationException when none of challenge types
        *  available is supported.
  +     * 
  +     * @deprecated Use {@link AuthChallengeParser#parseChallenges(Header[])} and 
  +     *      {@link AuthPolicy#getAuthScheme(String)}
        */
       public static AuthScheme selectAuthScheme(final Header[] challenges)
         throws MalformedChallengeException {
  
  
  
  1.12      +34 -5     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/NTLMScheme.java
  
  Index: NTLMScheme.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/NTLMScheme.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- NTLMScheme.java	16 Aug 2003 00:41:24 -0000	1.11
  +++ NTLMScheme.java	10 Dec 2003 21:04:13 -0000	1.12
  @@ -81,7 +81,7 @@
    * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
    * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
    */
  -public class NTLMScheme extends AuthSchemeBase {
  +public class NTLMScheme implements AuthScheme {
   
       /** Log object for this class. */
       private static final Log LOG = LogFactory.getLog(NTLMScheme.class);
  @@ -90,6 +90,14 @@
       private String ntlmchallenge = null;
   
       /**
  +     * Default constructor for the NTLM authentication scheme.
  +     * 
  +     */
  +    public NTLMScheme() {
  +        super();
  +    }
  +
  +    /**
        * Constructor for the NTLM authentication scheme.
        * 
        * @param challenge The authentication challenge
  @@ -98,7 +106,19 @@
        * is malformed
        */
       public NTLMScheme(final String challenge) throws MalformedChallengeException {
  -        super(challenge);
  +        super();
  +        processChallenge(challenge);
  +    }
  +
  +    /**
  +     * Processes the NTLM challenge.
  +     *  
  +     * @param the challenge string
  +     * 
  +     * @throws MalformedChallengeException is thrown if the authentication challenge
  +     * is malformed
  +     */
  +    public void processChallenge(final String challenge) throws MalformedChallengeException {
           String s = AuthChallengeParser.extractScheme(challenge);
           if (!s.equalsIgnoreCase(getSchemeName())) {
               throw new MalformedChallengeException("Invalid NTLM challenge: " + challenge);
  @@ -167,6 +187,15 @@
               throw new IllegalArgumentException("Parameter name may not be null"); 
           }
           return null;
  +    }
  +
  +    /**
  +     * Returns <tt>true</tt>. NTLM authentication scheme is connection based.
  +     * 
  +     * @return <tt>true</tt>.
  +     */
  +    public boolean isConnectionBased() {
  +        return true;    
       }
   
       /**
  
  
  
  1.5       +30 -5     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/RFC2617Scheme.java
  
  Index: RFC2617Scheme.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/RFC2617Scheme.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- RFC2617Scheme.java	22 Apr 2003 17:00:25 -0000	1.4
  +++ RFC2617Scheme.java	10 Dec 2003 21:04:13 -0000	1.5
  @@ -74,7 +74,7 @@
    *
    * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
   */
  -public abstract class RFC2617Scheme extends AuthSchemeBase {
  +public abstract class RFC2617Scheme implements AuthScheme {
   
       /**
        * Authentication parameter map.
  @@ -84,13 +84,38 @@
       /**
        * Default constructor for RFC2617 compliant authetication schemes.
        * 
  +     */
  +    public RFC2617Scheme() {
  +        super();
  +    }
  +
  +    /**
  +     * Default constructor for RFC2617 compliant authetication schemes.
  +     * 
        * @param challenge authentication challenge
        * 
        * @throws MalformedChallengeException is thrown if the authentication challenge
        * is malformed
  +     * 
  +     * @deprecated Use parameterless constructor and {@link AuthScheme#challenge(String)} 
  +     *             method
        */
       public RFC2617Scheme(final String challenge) throws MalformedChallengeException {
  -        super(challenge);
  +        super();
  +        processChallenge(challenge);
  +    }
  +
  +    /**
  +     * Processes the given challenge token. Some authentication schemes
  +     * may involve multiple challenge-response exchanges. Such schemes must be able 
  +     * to maintain the state information when dealing with sequential challenges 
  +     * 
  +     * @param the challenge string
  +     * 
  +     * @throws MalformedChallengeException is thrown if the authentication challenge
  +     * is malformed
  +     */
  +    public void processChallenge(final String challenge) throws MalformedChallengeException {
           String s = AuthChallengeParser.extractScheme(challenge);
           if (!s.equalsIgnoreCase(getSchemeName())) {
               throw new MalformedChallengeException(
  
  
  
  1.35      +44 -35    jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestAuthenticator.java
  
  Index: TestAuthenticator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestAuthenticator.java,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- TestAuthenticator.java	24 Nov 2003 22:17:02 -0000	1.34
  +++ TestAuthenticator.java	10 Dec 2003 21:04:13 -0000	1.35
  @@ -131,7 +131,8 @@
           HttpState state = new HttpState();
           HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
           try {
  -            AuthScheme authscheme = new BasicScheme(challenge);
  +            AuthScheme authscheme = new BasicScheme();
  +            authscheme.processChallenge(challenge);
               HttpAuthenticator.authenticate(authscheme, method, null, state);
               fail("Should have thrown HttpException");
           } catch(HttpException e) {
  @@ -144,7 +145,8 @@
           HttpState state = new HttpState();
           HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
           try {
  -            AuthScheme authscheme = new BasicScheme(challenge);
  +            AuthScheme authscheme = new BasicScheme();
  +            authscheme.processChallenge(challenge);
               HttpAuthenticator.authenticate(authscheme, method, null, state);
               fail("Should have thrown HttpException");
           } catch(HttpException e) {
  @@ -157,7 +159,8 @@
           HttpState state = new HttpState();
           HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
           try {
  -            AuthScheme authscheme = new BasicScheme(challenge);
  +            AuthScheme authscheme = new BasicScheme();
  +            authscheme.processChallenge(challenge);
               HttpAuthenticator.authenticate(authscheme, method, null, state);
               fail("Should have thrown HttpException");
           } catch(HttpException e) {
  @@ -169,7 +172,8 @@
           String challenge = "Basic realm=\"realm1\"";
           HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
           try {
  -            AuthScheme authscheme = new BasicScheme(challenge);
  +            AuthScheme authscheme = new BasicScheme();
  +            authscheme.processChallenge(challenge);
               HttpAuthenticator.authenticate(authscheme, method, null, null);
               fail("Should have thrown IllegalArgumentException");
           } catch(IllegalArgumentException e) {
  @@ -177,23 +181,13 @@
           }
       }
   
  -    public void testInvalidAuthenticationScheme() throws Exception {
  -        String challenge = "invalid realm=\"realm1\"";
  -        try{
  -            HttpAuthenticator.selectAuthScheme(
  -              new Header[] { new Header("WWW-Authenticate", challenge) });
  -            fail("Should have thrown UnsupportedOperationException");
  -        }catch (UnsupportedOperationException uoe){
  -            // expected
  -        }
  -    }
  -
       public void testBasicAuthenticationCaseInsensitivity() throws Exception {
           String challenge = "bAsIc ReAlM=\"realm1\"";
           HttpState state = new HttpState();
           state.setCredentials(null, null, new UsernamePasswordCredentials("username","password"));
           HttpMethod method = new SimpleHttpMethod(new Header("WwW-AuThEnTiCaTe", challenge));
  -        AuthScheme authscheme = new BasicScheme(challenge);
  +        AuthScheme authscheme = new BasicScheme();
  +        authscheme.processChallenge(challenge);
           assertTrue(HttpAuthenticator.authenticate(authscheme, method, null, state));
           assertTrue(null != method.getRequestHeader("Authorization"));
           String expected = "Basic " + HttpConstants.getString(Base64.encode(HttpConstants.getBytes("username:password")));
  @@ -216,7 +210,8 @@
           HttpState state = new HttpState();
           state.setCredentials("realm", null, new UsernamePasswordCredentials("username","password"));
           HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
  -        AuthScheme authscheme = new BasicScheme(challenge);
  +        AuthScheme authscheme = new BasicScheme();
  +        authscheme.processChallenge(challenge);
           assertTrue(HttpAuthenticator.authenticate(authscheme, method, null, state));
           assertTrue(null != method.getRequestHeader("Authorization"));
           String expected = "Basic " + HttpConstants.getString(Base64.encode(HttpConstants.getBytes("username:password")));
  @@ -240,8 +235,10 @@
           HttpState state = new HttpState();
           state.setCredentials("realm1", null, new UsernamePasswordCredentials("username","password"));
           state.setCredentials("realm2", null, new UsernamePasswordCredentials("uname2","password2"));
  -        AuthScheme authscheme1 = new BasicScheme(challenge1);
  -        AuthScheme authscheme2 = new BasicScheme(challenge2);
  +        AuthScheme authscheme1 = new BasicScheme();
  +        authscheme1.processChallenge(challenge1);
  +        AuthScheme authscheme2 = new BasicScheme();
  +        authscheme2.processChallenge(challenge2);
           {
               HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate",challenge1));
               assertTrue(HttpAuthenticator.authenticate(authscheme1, method, null, state));
  @@ -284,7 +281,8 @@
           HttpState state = new HttpState();
           HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
           try {
  -            AuthScheme authscheme = new DigestScheme(challenge);
  +            AuthScheme authscheme = new DigestScheme();
  +            authscheme.processChallenge(challenge);
               HttpAuthenticator.authenticate(authscheme, method, null, state);
               fail("Should have thrown HttpException");
           } catch(HttpException e) {
  @@ -297,7 +295,8 @@
           HttpState state = new HttpState();
           HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
           try {
  -            AuthScheme authscheme = new DigestScheme(challenge);
  +            AuthScheme authscheme = new DigestScheme();
  +            authscheme.processChallenge(challenge);
               HttpAuthenticator.authenticate(authscheme, method, null, state);
               fail("Should have thrown HttpException");
           } catch(HttpException e) {
  @@ -310,7 +309,8 @@
           HttpState state = new HttpState();
           HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
           try {
  -            AuthScheme authscheme = new DigestScheme(challenge);
  +            AuthScheme authscheme = new DigestScheme();
  +            authscheme.processChallenge(challenge);
               HttpAuthenticator.authenticate(authscheme, method, null, state);
               fail("Should have thrown HttpException");
           } catch(HttpException e) {
  @@ -322,7 +322,8 @@
           String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\"";
           HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
           try {
  -            AuthScheme authscheme = new DigestScheme(challenge);
  +            AuthScheme authscheme = new DigestScheme();
  +            authscheme.processChallenge(challenge);
               HttpAuthenticator.authenticate(authscheme, method, null, null);
               fail("Should have thrown IllegalArgumentException");
           } catch(IllegalArgumentException e) {
  @@ -336,7 +337,8 @@
           UsernamePasswordCredentials cred = new UsernamePasswordCredentials("username","password");
           state.setCredentials(null, null, cred);
           HttpMethod method = new SimpleHttpMethod(new Header("WwW-AuThEnTiCaTe", challenge));
  -        AuthScheme authscheme = new DigestScheme(challenge);
  +        AuthScheme authscheme = new DigestScheme();
  +        authscheme.processChallenge(challenge);
           assertTrue(HttpAuthenticator.authenticate(authscheme, method, null, state));
           assertTrue(null != method.getRequestHeader("Authorization"));
       }
  @@ -348,7 +350,8 @@
           UsernamePasswordCredentials cred = new UsernamePasswordCredentials("username","password");
           state.setCredentials(null, null, cred);
           HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
  -        AuthScheme authscheme = new DigestScheme(challenge);
  +        AuthScheme authscheme = new DigestScheme();
  +        authscheme.processChallenge(challenge);
           assertTrue(HttpAuthenticator.authenticate(authscheme, method, null, state));
           assertTrue(null != method.getRequestHeader("Authorization"));
           Map table = AuthChallengeParser.extractParams(method.getRequestHeader("Authorization").getValue());
  @@ -365,7 +368,8 @@
           UsernamePasswordCredentials cred = new UsernamePasswordCredentials("username","password");
           state.setCredentials(null, null, cred);
           HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
  -        AuthScheme authscheme = new DigestScheme(challenge);
  +        AuthScheme authscheme = new DigestScheme();
  +        authscheme.processChallenge(challenge);
           assertTrue(HttpAuthenticator.authenticate(authscheme, method, null, state));
           assertTrue(null != method.getRequestHeader("Authorization"));
           Map table = AuthChallengeParser.extractParams(method.getRequestHeader("Authorization").getValue());
  @@ -423,8 +427,10 @@
           state.setCredentials("realm1", null, cred);
           UsernamePasswordCredentials cred2 = new UsernamePasswordCredentials("uname2","password2");
           state.setCredentials("realm2", null, cred2);
  -        AuthScheme authscheme1 = new DigestScheme(challenge1);
  -        AuthScheme authscheme2 = new DigestScheme(challenge2);
  +        AuthScheme authscheme1 = new DigestScheme();
  +        authscheme1.processChallenge(challenge1);
  +        AuthScheme authscheme2 = new DigestScheme();
  +        authscheme2.processChallenge(challenge2);
           {
               HttpMethod method = new SimpleHttpMethod(new Header("WWW-Authenticate",challenge1));
               assertTrue(HttpAuthenticator.authenticate(authscheme1, method, null, state));
  @@ -471,7 +477,8 @@
           UsernamePasswordCredentials cred =
               new UsernamePasswordCredentials(username, password);
           state.setCredentials(realm, null, cred);
  -        AuthScheme authscheme = new DigestScheme(challenge);
  +        AuthScheme authscheme = new DigestScheme();
  +        authscheme.processChallenge(challenge);
           HttpMethod method =
               new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
           assertTrue(HttpAuthenticator.authenticate(
  @@ -512,7 +519,8 @@
           UsernamePasswordCredentials cred =
               new UsernamePasswordCredentials(username, password);
           state.setCredentials(realm, null, cred);
  -        AuthScheme authscheme = new DigestScheme(challenge);
  +        AuthScheme authscheme = new DigestScheme();
  +        authscheme.processChallenge(challenge);
           HttpMethod method =
               new SimpleHttpMethod(new Header("WWW-Authenticate", challenge));
           assertTrue(HttpAuthenticator.authenticate(
  @@ -554,7 +562,8 @@
               new UsernamePasswordCredentials(username, password);
           state.setCredentials(realm, null, cred);
           try {
  -            AuthScheme authscheme = new DigestScheme(challenge);
  +            AuthScheme authscheme = new DigestScheme();
  +            authscheme.processChallenge(challenge);
               fail("MalformedChallengeException exception expected due to invalid qop value");
           } catch(MalformedChallengeException e) {
               /* expected */
  
  
  
  1.3       +5 -4      jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/server/ProxyAuthRequestHandler.java
  
  Index: ProxyAuthRequestHandler.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/server/ProxyAuthRequestHandler.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ProxyAuthRequestHandler.java	5 Dec 2003 21:23:15 -0000	1.2
  +++ ProxyAuthRequestHandler.java	10 Dec 2003 21:04:13 -0000	1.3
  @@ -142,7 +142,8 @@
   		// TODO Auto-generated method stub
   		BasicScheme scheme;
   		try {
  -			scheme = new BasicScheme("basic realm=test");
  +			scheme = new BasicScheme();
  +            scheme.processChallenge("basic realm=test");
   			String expectedAuthString = scheme.authenticate(credentials, null, null);
   			return expectedAuthString.equals(clientAuth.getValue());
   		} catch (MalformedChallengeException e) {
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org