Index: src/examples/AlternateAuthenticationExample.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/examples/AlternateAuthenticationExample.java,v retrieving revision 1.2 diff -u -r1.2 AlternateAuthenticationExample.java --- src/examples/AlternateAuthenticationExample.java 22 Feb 2004 18:08:45 -0000 1.2 +++ src/examples/AlternateAuthenticationExample.java 12 Jun 2004 17:26:21 -0000 @@ -1,5 +1,5 @@ /* - * $Header: /home/cvspublic/jakarta-commons/httpclient/src/examples/AlternateAuthenticationExample.java,v 1.2 2004/02/22 18:08:45 olegk Exp $ + * $Header: /home/cvs/jakarta-commons/httpclient/src/examples/AlternateAuthenticationExample.java,v 1.2 2004/02/22 18:08:45 olegk Exp $ * $Revision: 1.2 $ * $Date: 2004/02/22 18:08:45 $ * ==================================================================== @@ -34,6 +34,7 @@ import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthPolicy; +import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.GetMethod; /** @@ -59,7 +60,8 @@ public static void main(String[] args) throws Exception { HttpClient client = new HttpClient(); - client.getState().setCredentials("myrealm", "myhost", + client.getState().setCredentials( + new AuthScope("myhost", 80, "myrealm"), new UsernamePasswordCredentials("username", "password")); // Suppose the site supports several authetication schemes: NTLM and Basic // Basic authetication is considered inherently insecure. Hence, NTLM authentication Index: src/examples/BasicAuthenticationExample.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/examples/BasicAuthenticationExample.java,v retrieving revision 1.3 diff -u -r1.3 BasicAuthenticationExample.java --- src/examples/BasicAuthenticationExample.java 22 Feb 2004 18:08:45 -0000 1.3 +++ src/examples/BasicAuthenticationExample.java 12 Jun 2004 17:26:21 -0000 @@ -1,5 +1,5 @@ /* - * $Header: /home/cvspublic/jakarta-commons/httpclient/src/examples/BasicAuthenticationExample.java,v 1.3 2004/02/22 18:08:45 olegk Exp $ + * $Header: /home/cvs/jakarta-commons/httpclient/src/examples/BasicAuthenticationExample.java,v 1.3 2004/02/22 18:08:45 olegk Exp $ * $Revision: 1.3 $ * $Date: 2004/02/22 18:08:45 $ * ==================================================================== @@ -30,6 +30,7 @@ import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.GetMethod; /** @@ -57,8 +58,7 @@ // "www.verisign.com", to authenticate against // an arbitrary realm or host change the appropriate argument to null. client.getState().setCredentials( - "realm", - "www.verisign.com", + new AuthScope("www.verisign.com", 443, "realm"), new UsernamePasswordCredentials("username", "password") ); Index: src/examples/ProxyTunnelDemo.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/examples/ProxyTunnelDemo.java,v retrieving revision 1.1 diff -u -r1.1 ProxyTunnelDemo.java --- src/examples/ProxyTunnelDemo.java 13 Apr 2004 02:08:30 -0000 1.1 +++ src/examples/ProxyTunnelDemo.java 12 Jun 2004 17:26:21 -0000 @@ -6,7 +6,7 @@ import org.apache.commons.httpclient.ProxyClient; import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.HttpAuthRealm; +import org.apache.commons.httpclient.auth.AuthScope; /* * $Header: /home/cvspublic/jakarta-commons/httpclient/src/examples/ProxyTunnelDemo.java,v 1.1 2004/04/13 02:08:30 mbecke Exp $ @@ -59,7 +59,7 @@ proxyclient.getHostConfiguration().setProxy("10.0.1.1", 3128); // set the proxy credentials, only necessary for authenticating proxies proxyclient.getState().setProxyCredentials( - new HttpAuthRealm("10.0.1.1", 3128, null), + new AuthScope("10.0.1.1", 3128, null), new UsernamePasswordCredentials("proxy", "proxy")); // create the socket Index: src/examples/TrivialApp.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/examples/TrivialApp.java,v retrieving revision 1.17 diff -u -r1.17 TrivialApp.java --- src/examples/TrivialApp.java 22 Feb 2004 18:08:45 -0000 1.17 +++ src/examples/TrivialApp.java 12 Jun 2004 17:26:22 -0000 @@ -1,5 +1,5 @@ /* - * $Header: /home/cvspublic/jakarta-commons/httpclient/src/examples/TrivialApp.java,v 1.17 2004/02/22 18:08:45 olegk Exp $ + * $Header: /home/cvs/jakarta-commons/httpclient/src/examples/TrivialApp.java,v 1.17 2004/02/22 18:08:45 olegk Exp $ * $Revision: 1.17 $ * $Date: 2004/02/22 18:08:45 $ * @@ -37,6 +37,7 @@ import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.UsernamePasswordCredentials; +import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.GetMethod; /** @@ -83,7 +84,7 @@ //set the default credentials if (creds != null) { - client.getState().setCredentials(null, null, creds); + client.getState().setCredentials(AuthScope.ANY, creds); } String url = args[0]; @@ -136,7 +137,6 @@ //clean up the connection resources method.releaseConnection(); - method.recycle(); System.exit(0); } Index: src/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.25 diff -u -r1.25 HttpMethodDirector.java --- src/java/org/apache/commons/httpclient/HttpMethodDirector.java 13 May 2004 04:03:25 -0000 1.25 +++ src/java/org/apache/commons/httpclient/HttpMethodDirector.java 12 Jun 2004 17:26:24 -0000 @@ -42,7 +42,7 @@ import org.apache.commons.httpclient.auth.AuthenticationException; import org.apache.commons.httpclient.auth.CredentialsProvider; import org.apache.commons.httpclient.auth.CredentialsNotAvailableException; -import org.apache.commons.httpclient.auth.HttpAuthRealm; +import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.auth.MalformedChallengeException; import org.apache.commons.httpclient.params.HttpClientParams; import org.apache.commons.httpclient.params.HttpConnectionParams; @@ -261,21 +261,27 @@ host = conn.getHost(); } int port = conn.getPort(); - HttpAuthRealm realm = new HttpAuthRealm( + AuthScope authscope = new AuthScope( host, port, authscheme.getRealm(), authscheme.getSchemeName()); if (LOG.isDebugEnabled()) { - LOG.debug("Authenticating with " + realm); + LOG.debug("Authenticating with " + authscope); } - Credentials credentials = this.state.getCredentials(realm); + Credentials credentials = this.state.getCredentials(authscope); if (credentials != null) { String authstring = authscheme.authenticate(credentials, method); if (authstring != null) { method.addRequestHeader(new Header(WWW_AUTH_RESP, authstring, true)); } } else { - LOG.warn("Required credentials not available"); + if (LOG.isWarnEnabled()) { + LOG.warn("Required credentials not available for " + authscope); + if (method.getHostAuthState().isPreemptive()) { + LOG.warn("Preemptive authentication requested but no default " + + "credentials available"); + } + } } } } @@ -292,21 +298,27 @@ return; } if ((this.authProcess == AUTH_PROXY_REQUIRED) || (!authscheme.isConnectionBased())) { - HttpAuthRealm realm = new HttpAuthRealm( + AuthScope authscope = new AuthScope( conn.getProxyHost(), conn.getProxyPort(), authscheme.getRealm(), authscheme.getSchemeName()); if (LOG.isDebugEnabled()) { - LOG.debug("Authenticating with " + realm); + LOG.debug("Authenticating with " + authscope); } - Credentials credentials = this.state.getProxyCredentials(realm); + Credentials credentials = this.state.getProxyCredentials(authscope); if (credentials != null) { String authstring = authscheme.authenticate(credentials, method); if (authstring != null) { method.addRequestHeader(new Header(PROXY_AUTH_RESP, authstring, true)); } } else { - LOG.warn("Required credentials not available"); + if (LOG.isWarnEnabled()) { + LOG.warn("Required proxy credentials not available for " + authscope); + if (method.getProxyAuthState().isPreemptive()) { + LOG.warn("Preemptive authentication requested but no default " + + "proxy credentials available"); + } + } } } } @@ -632,7 +644,7 @@ host = conn.getHost(); } int port = conn.getPort(); - HttpAuthRealm realm = new HttpAuthRealm( + AuthScope authscope = new AuthScope( host, port, authscheme.getRealm(), authscheme.getSchemeName()); @@ -640,10 +652,10 @@ if ((this.authProcess == AUTH_WWW_REQUIRED) && (authscheme.isComplete())) { // Already tried and failed Credentials credentials = promptForCredentials( - authscheme, method.getParams(), realm); + authscheme, method.getParams(), authscope); if (credentials == null) { if (LOG.isInfoEnabled()) { - LOG.info("Failure authenticating with " + realm); + LOG.info("Failure authenticating with " + authscope); } return false; } else { @@ -652,14 +664,14 @@ } else { this.authProcess = AUTH_WWW_REQUIRED; - Credentials credentials = this.state.getCredentials(realm); + Credentials credentials = this.state.getCredentials(authscope); if (credentials == null) { credentials = promptForCredentials( - authscheme, method.getParams(), realm); + authscheme, method.getParams(), authscope); } if (credentials == null) { if (LOG.isInfoEnabled()) { - LOG.info("No credentials available for the " + realm); + LOG.info("No credentials available for " + authscope); } return false; } else { @@ -691,7 +703,7 @@ if (authscheme == null) { return false; } - HttpAuthRealm realm = new HttpAuthRealm( + AuthScope authscope = new AuthScope( conn.getProxyHost(), conn.getProxyPort(), authscheme.getRealm(), authscheme.getSchemeName()); @@ -699,10 +711,10 @@ if ((this.authProcess == AUTH_PROXY_REQUIRED) && (authscheme.isComplete())) { // Already tried and failed Credentials credentials = promptForProxyCredentials( - authscheme, method.getParams(), realm); + authscheme, method.getParams(), authscope); if (credentials == null) { if (LOG.isInfoEnabled()) { - LOG.info("Failure authenticating with " + realm); + LOG.info("Failure authenticating with " + authscope); } return false; } else { @@ -711,14 +723,14 @@ } else { this.authProcess = AUTH_PROXY_REQUIRED; - Credentials credentials = this.state.getProxyCredentials(realm); + Credentials credentials = this.state.getProxyCredentials(authscope); if (credentials == null) { credentials = promptForProxyCredentials( - authscheme, method.getParams(), realm); + authscheme, method.getParams(), authscope); } if (credentials == null) { if (LOG.isInfoEnabled()) { - LOG.info("No proxy credentials available for the " + realm); + LOG.info("No credentials available for " + authscope); } return false; } else { @@ -780,7 +792,7 @@ private Credentials promptForCredentials( final AuthScheme authScheme, final HttpParams params, - final HttpAuthRealm realm) + final AuthScope authscope) { Credentials creds = null; CredentialsProvider credProvider = @@ -788,14 +800,14 @@ if (credProvider != null) { try { creds = credProvider.getCredentials( - authScheme, realm.getHost(), realm.getPort(), false); + authScheme, authscope.getHost(), authscope.getPort(), false); } catch (CredentialsNotAvailableException e) { LOG.warn(e.getMessage()); } if (creds != null) { - this.state.setCredentials(realm, creds); + this.state.setCredentials(authscope, creds); if (LOG.isDebugEnabled()) { - LOG.debug("New credentials for " + realm); + LOG.debug(authscope + " new credentials given"); } } } @@ -805,7 +817,7 @@ private Credentials promptForProxyCredentials( final AuthScheme authScheme, final HttpParams params, - final HttpAuthRealm realm) + final AuthScope authscope) { Credentials creds = null; CredentialsProvider credProvider = @@ -813,14 +825,14 @@ if (credProvider != null) { try { creds = credProvider.getCredentials( - authScheme, realm.getHost(), realm.getPort(), true); + authScheme, authscope.getHost(), authscope.getPort(), true); } catch (CredentialsNotAvailableException e) { LOG.warn(e.getMessage()); } if (creds != null) { - this.state.setProxyCredentials(realm, creds); + this.state.setProxyCredentials(authscope, creds); if (LOG.isDebugEnabled()) { - LOG.debug("New proxy credentials for " + realm); + LOG.debug(authscope + " new credentials given"); } } } Index: src/java/org/apache/commons/httpclient/HttpState.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpState.java,v retrieving revision 1.33 diff -u -r1.33 HttpState.java --- src/java/org/apache/commons/httpclient/HttpState.java 13 May 2004 04:03:25 -0000 1.33 +++ src/java/org/apache/commons/httpclient/HttpState.java 12 Jun 2004 17:26:26 -0000 @@ -37,7 +37,7 @@ import java.util.Iterator; import org.apache.commons.httpclient.cookie.CookieSpec; import org.apache.commons.httpclient.cookie.CookiePolicy; -import org.apache.commons.httpclient.auth.HttpAuthRealm; +import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -47,11 +47,6 @@ * to request, such as {@link Cookie cookies} and authentication * {@link Credentials credentials}. *

- *

- * Preemptive authentication can be turned on by using the property value of - * #PREEMPTIVE_PROPERTY. If left unspecified, it has the default value of - * #PREEMPTIVE_DEFAULT. This configurable behaviour conforms to rcf2617: - *

* * @author Remy Maucherat * @author Rodney Waldhoff @@ -315,73 +310,75 @@ * have been explictly supplied for the challenging host. Any previous * credentials for the given realm on the given host will be overwritten. * - * @param realm the authentication realm + * @param scope the authentication scope * @param host the host the realm belongs to * @param credentials the authentication {@link Credentials credentials} * for the given realm. * * @see #getCredentials(String, String) * @see #setProxyCredentials(String, String, Credentials) + * + * @deprecated use #setCredentials(AuthScope, Credentials) */ public synchronized void setCredentials(String realm, String host, Credentials credentials) { LOG.trace("enter HttpState.setCredentials(String, String, Credentials)"); - credMap.put(new HttpAuthRealm(host, realm), credentials); + credMap.put(new AuthScope(host, AuthScope.ANY_PORT, realm, AuthScope.ANY_SCHEME), credentials); } /** * Sets the {@link Credentials credentials} for the given authentication - * realm. Any previous credentials for the given realm will be overwritten. + * scope. Any previous credentials for the given scope will be overwritten. * - * @param realm the {@link HttpAuthRealm authentication realm} + * @param scope the {@link AuthScope authentication scope} * @param credentials the authentication {@link Credentials credentials} - * for the given realm. + * for the given scope. * - * @see #getCredentials(HttpAuthRealm) - * @see #setProxyCredentials(HttpAuthRealm, Credentials) + * @see #getCredentials(AuthScope) + * @see #setProxyCredentials(AuthScope, Credentials) * * @since 3.0 */ - public synchronized void setCredentials(final HttpAuthRealm realm, Credentials credentials) { - if (realm == null) { - throw new IllegalArgumentException("Authentication realm token may not be null"); + public synchronized void setCredentials(final AuthScope authscope, final Credentials credentials) { + if (authscope == null) { + throw new IllegalArgumentException("Authentication scope may not be null"); } - LOG.trace("enter HttpState.setCredentials(HttpAuthRealm, Credentials)"); - credMap.put(realm, credentials); + LOG.trace("enter HttpState.setCredentials(AuthScope, Credentials)"); + credMap.put(authscope, credentials); } /** - * Find matching {@link Credentials credentials} for the given authentication realm. + * Find matching {@link Credentials credentials} for the given authentication scope. * * @param map the credentials hash map - * @param token the {@link HttpAuthRealm authentication realm token} + * @param token the {@link AuthScope authentication scope} * @return the credentials * */ - private static Credentials matchCredentials(HashMap map, HttpAuthRealm token) { - HttpAuthRealm key = token; + private static Credentials matchCredentials(HashMap map, AuthScope token) { + AuthScope key = token; Credentials creds = (Credentials) map.get(key); if (creds == null && token.getScheme() != null) { - key = new HttpAuthRealm(token.getHost(), token.getPort(), token.getRealm()); + key = new AuthScope(token.getHost(), token.getPort(), token.getRealm()); creds = (Credentials) map.get(key); } if (creds == null && token.getRealm() != null) { - key = new HttpAuthRealm(token.getHost(), token.getPort()); + key = new AuthScope(token.getHost(), token.getPort()); creds = (Credentials) map.get(key); } if (creds == null && token.getPort() >= 0) { - key = new HttpAuthRealm(token.getHost(), -1); + key = new AuthScope(token.getHost(), -1); creds = (Credentials) map.get(key); } if (creds == null && token.getHost() != null) { - key = new HttpAuthRealm(); + key = AuthScope.ANY; creds = (Credentials) map.get(key); } return creds; } /** - * Get the {@link Credentials credentials} for the given authentication realm on the + * Get the {@link Credentials credentials} for the given authentication scope on the * given host. * * If the realm exists on host, return the coresponding credentials. @@ -392,34 +389,37 @@ * the default Credentials. If there are no default credentials, return * null. * - * @param realm the authentication realm + * @param scope the authentication scope * @param host the host the realm is on * @return the credentials * * @see #setCredentials(String, String, Credentials) + * + * @deprecated use #getCredentials(AuthScope) */ public synchronized Credentials getCredentials(String realm, String host) { LOG.trace("enter HttpState.getCredentials(String, String"); - return matchCredentials(this.credMap, new HttpAuthRealm(host, realm)); + return matchCredentials(this.credMap, + new AuthScope(host, AuthScope.ANY_PORT, realm, AuthScope.ANY_SCHEME)); } /** - * Get the {@link Credentials credentials} for the given authentication realm. + * Get the {@link Credentials credentials} for the given authentication scope. * - * @param realm the {@link HttpAuthRealm authentication realm} + * @param scope the {@link AuthScope authentication scope} * @return the credentials * - * @see #setCredentials(HttpAuthRealm, Credentials) + * @see #setCredentials(AuthScope, Credentials) * * @since 3.0 */ - public synchronized Credentials getCredentials(HttpAuthRealm realm) { - if (realm == null) { - throw new IllegalArgumentException("Authentication realm token may not be null"); + public synchronized Credentials getCredentials(final AuthScope authscope) { + if (authscope == null) { + throw new IllegalArgumentException("Authentication scope may not be null"); } - LOG.trace("enter HttpState.getCredentials(HttpAuthRealm)"); - return matchCredentials(this.credMap, realm); + LOG.trace("enter HttpState.getCredentials(AuthScope)"); + return matchCredentials(this.credMap, authscope); } /** @@ -433,12 +433,14 @@ * credentials for the given proxy realm on the given proxy host will be * overwritten. * - * @param realm the authentication realm + * @param scope the authentication scope * @param proxyHost the proxy host * @param credentials the authentication credentials for the given realm * - * @see #getProxyCredentials(String,String) - * @see #setCredentials(String, String, Credentials) + * @see #getProxyCredentials(AuthScope) + * @see #setCredentials(AuthScope, Credentials) + * + * @deprecated use #setProxyCredentials(AuthScope, Credentials) */ public synchronized void setProxyCredentials( String realm, @@ -446,35 +448,35 @@ Credentials credentials ) { LOG.trace("enter HttpState.setProxyCredentials(String, String, Credentials"); - proxyCred.put(new HttpAuthRealm(proxyHost, realm), credentials); + proxyCred.put(new AuthScope(proxyHost, AuthScope.ANY_PORT, realm, AuthScope.ANY_SCHEME), credentials); } /** - * Sets the {@link Credentials credentials} for the given proxy authentication + * Sets the {@link Credentials proxy credentials} for the given authentication * realm. Any previous credentials for the given realm will be overwritten. * - * @param realm the {@link HttpAuthRealm authentication realm} + * @param scope the {@link AuthScope authentication scope} * @param credentials the authentication {@link Credentials credentials} * for the given realm. * - * @see #getProxyCredentials(HttpAuthRealm) - * @see #setCredentials(HttpAuthRealm, Credentials) + * @see #getProxyCredentials(AuthScope) + * @see #setCredentials(AuthScope, Credentials) * * @since 3.0 */ - public synchronized void setProxyCredentials(final HttpAuthRealm realm, - Credentials credentials) + public synchronized void setProxyCredentials(final AuthScope authscope, + final Credentials credentials) { - if (realm == null) { - throw new IllegalArgumentException("Authentication realm token may not be null"); + if (authscope == null) { + throw new IllegalArgumentException("Authentication scope may not be null"); } - LOG.trace("enter HttpState.setProxyCredentials(HttpAuthRealm, Credentials)"); - proxyCred.put(realm, credentials); + LOG.trace("enter HttpState.setProxyCredentials(AuthScope, Credentials)"); + proxyCred.put(authscope, credentials); } /** * Get the {@link Credentials credentials} for the proxy host with the given - * authentication realm. + * authentication scope. * * If the realm exists on host, return the coresponding credentials. * If the host exists with a null realm, return the corresponding @@ -484,32 +486,35 @@ * the default Credentials. If there are no default credentials, return * null. * - * @param realm the authentication realm + * @param scope the authentication scope * @param proxyHost the proxy host the realm is on * @return the credentials * @see #setProxyCredentials(String, String, Credentials) + * + * @deprecated use #getProxyCredentials(AuthScope) */ public synchronized Credentials getProxyCredentials(String realm, String proxyHost) { LOG.trace("enter HttpState.getCredentials(String, String"); - return matchCredentials(this.proxyCred, new HttpAuthRealm(proxyHost, realm)); + return matchCredentials(this.proxyCred, + new AuthScope(proxyHost, AuthScope.ANY_PORT, realm, AuthScope.ANY_SCHEME)); } /** - * Get the {@link Credentials credentials} for the given proxy authentication realm. + * Get the {@link Credentials proxy credentials} for the given authentication scope. * - * @param realm the {@link HttpAuthRealm authentication realm} + * @param scope the {@link AuthScope authentication scope} * @return the credentials * - * @see #setProxyCredentials(HttpAuthRealm, Credentials) + * @see #setProxyCredentials(AuthScope, Credentials) * * @since 3.0 */ - public synchronized Credentials getProxyCredentials(HttpAuthRealm realm) { - if (realm == null) { - throw new IllegalArgumentException("Authentication realm token may not be null"); + public synchronized Credentials getProxyCredentials(final AuthScope authscope) { + if (authscope == null) { + throw new IllegalArgumentException("Authentication scope may not be null"); } - LOG.trace("enter HttpState.getProxyCredentials(HttpAuthRealm)"); - return matchCredentials(this.proxyCred, realm); + LOG.trace("enter HttpState.getProxyCredentials(AuthScope)"); + return matchCredentials(this.proxyCred, authscope); } /** Index: src/java/org/apache/commons/httpclient/auth/AuthScope.java =================================================================== RCS file: src/java/org/apache/commons/httpclient/auth/AuthScope.java diff -N src/java/org/apache/commons/httpclient/auth/AuthScope.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/java/org/apache/commons/httpclient/auth/AuthScope.java 12 Jun 2004 17:26:27 -0000 @@ -0,0 +1,288 @@ +/* + * $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 + * . + * + */ + +package org.apache.commons.httpclient.auth; + +/** + * The class represents an authentication scope consisting of a host name, + * a port number, a realm name and an authentication scheme name which + * {@link Credentials} apply to. + * + * @author Oleg Kalnichevski + * @author Adrian Sutton + * + * @since 3.0 + */ +public class AuthScope { + + /** + * The null value represents any host. In the future versions of + * HttpClient the use of this parameter will be discontinued. + */ + public static String ANY_HOST = null; + + /** + * The -1 value represents any port. + */ + public static int ANY_PORT = -1; + + /** + * The null value represents any realm. + */ + public static String ANY_REALM = null; + + /** + * The null value represents any authentication scheme. + */ + public static String ANY_SCHEME = null; + + /** + * Default scope matching any host, port, realm and authentication scheme. + */ + public static AuthScope ANY = new AuthScope(ANY_HOST, ANY_PORT, ANY_REALM, ANY_SCHEME); + + /** The authentication scheme the credentials apply to. */ + private String scheme = null; + + /** The realm the credentials apply to. */ + private String realm = null; + + /** The host the credentials apply to. */ + private String host = null; + + /** The port the credentials apply to. */ + private int port = -1; + + /** Creates a new credentials scope for the given + * host, port, realm, and + * authentication scheme. + * + * @param host the host the credentials apply to. May be set + * to null if credenticals are applicable to + * any host. + * @param port the port the credentials apply to. May be set + * to negative value if credenticals are applicable to + * any port. + * @param realm the realm the credentials apply to. May be set + * to null if credenticals are applicable to + * any realm. + * @param scheme the authentication scheme the credentials apply to. + * May be set to null if credenticals are applicable to + * any authentication scheme. + * + * @since 3.0 + */ + public AuthScope(final String host, int port, + final String realm, final String scheme) + { + this.host = host; + this.port = port; + this.realm = realm; + this.scheme = scheme; + } + + /** Creates a new credentials scope for the given + * host, port, realm, and any + * authentication scheme. + * + * @param host the host the credentials apply to. May be set + * to null if credenticals are applicable to + * any host. + * @param port the port the credentials apply to. May be set + * to negative value if credenticals are applicable to + * any port. + * @param realm the realm the credentials apply to. May be set + * to null if credenticals are applicable to + * any realm. + * + * @since 3.0 + */ + public AuthScope(final String host, int port, final String realm) { + this(host, port, realm, ANY_SCHEME); + } + + /** Creates a new credentials scope for the given + * host, port, any realm name, and any + * authentication scheme. + * + * @param host the host the credentials apply to. May be set + * to null if credenticals are applicable to + * any host. + * @param port the port the credentials apply to. May be set + * to negative value if credenticals are applicable to + * any port. + * + * @since 3.0 + */ + public AuthScope(final String host, int port) { + this(host, port, ANY_REALM, ANY_SCHEME); + } + + /** + * Creates a copy of the given credentials scope. + * + * @since 3.0 + */ + public AuthScope(final AuthScope authscope) { + super(); + if (authscope == null) { + throw new IllegalArgumentException("Scope may not be null"); + } + this.host = authscope.getHost(); + this.port = authscope.getPort(); + this.realm = authscope.getRealm(); + this.scheme = authscope.getScheme(); + } + + /** + * @return the host + * + * @since 3.0 + */ + public String getHost() { + return this.host; + } + + /** + * @return the port + * + * @since 3.0 + */ + public int getPort() { + return this.port; + } + + /** + * @return the realm name + * + * @since 3.0 + */ + public String getRealm() { + return this.realm; + } + + /** + * @return the scheme type + * + * @since 3.0 + */ + public String getScheme() { + return this.scheme; + } + + /** Determines if the given parameters match. Note that null acts as a + * wildcard so if either of the parameters are null, it is considered a match. + * + * @param p1 the parameter + * @param p2 the other parameter + * @return boolean true if the parameters match, otherwise false. + */ + private static boolean paramsMatchIgnoreCase(final String p1, final String p2) { + return p1 == null || p2 == null || p1.equalsIgnoreCase(p2); + } + + /** Determines if the given parameters match. Note that null acts as a + * wildcard so if either of the parameters are null, it is considered a match. + * + * @param p1 the parameter + * @param p2 the other parameter + * @return boolean true if the parameters match, otherwise false. + */ + private static boolean paramsMatch(final String p1, final String p2) { + return p1 == null || p2 == null || p1.equals(p2); + } + + /** Determines if the given parameters match. Note that negative value acts as a + * wildcard so if either of the parameters are negative, it is considered a match. + * + * @param p1 the parameter + * @param p2 the other parameter + * @return boolean true if the parameters match, otherwise false. + */ + private static boolean paramsMatch(int p1, int p2) { + return p1 < 0 || p2 < 0 || p1 == p2; + } + + /** + * @see java.lang.Object#equals(Object) + */ + public boolean equals(Object o) { + if (o == null) { + return false; + } + if (o == this) { + return true; + } + if (!(o instanceof AuthScope)) { + return super.equals(o); + } + AuthScope that = (AuthScope) o; + return + paramsMatchIgnoreCase(this.host, that.host) + && paramsMatch(this.port, that.port) + && paramsMatch(this.realm, that.realm) + && paramsMatchIgnoreCase(this.scheme, that.scheme); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buffer = new StringBuffer(); + if (this.scheme != null) { + buffer.append(this.scheme.toUpperCase()); + buffer.append(' '); + } + if (this.realm != null) { + buffer.append('\''); + buffer.append(this.realm); + buffer.append('\''); + } else { + buffer.append(""); + } + if (this.host != null) { + buffer.append('@'); + buffer.append(this.host); + if (this.port >= 0) { + buffer.append(':'); + buffer.append(this.port); + } + } + return buffer.toString(); + } + /** + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return ((this.host != null) ? this.host.toLowerCase().hashCode() : 0) + + ((this.port >= 0) ? this.port : -1) + + ((this.realm != null) ? this.realm.hashCode() : 0) + + ((this.scheme != null) ? this.scheme.toLowerCase().hashCode() : 0); + } +} Index: src/java/org/apache/commons/httpclient/auth/HttpAuthRealm.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/HttpAuthRealm.java,v retrieving revision 1.8 diff -u -r1.8 HttpAuthRealm.java --- src/java/org/apache/commons/httpclient/auth/HttpAuthRealm.java 13 May 2004 04:02:00 -0000 1.8 +++ src/java/org/apache/commons/httpclient/auth/HttpAuthRealm.java 12 Jun 2004 17:26:27 -0000 @@ -33,243 +33,24 @@ * * @author Oleg Kalnichevski * @author Adrian Sutton + * + * @deprecated no longer used */ -public class HttpAuthRealm { +public class HttpAuthRealm extends AuthScope { - /** The authentication scheme the credentials apply to. */ - private String scheme = null; - - /** The realm the credentials apply to. */ - private String realm = null; - - /** The host the credentials apply to. */ - private String host = null; - - /** The port the credentials apply to. */ - private int port = -1; - - /** Creates a new authentication realm token for the given - * host, port, realm, and - * authentication scheme. - * - * @param host the host the credentials apply to. May be set - * to null if credenticals are applicable to - * any host. - * @param port the port the credentials apply to. May be set - * to negative value if credenticals are applicable to - * any port. - * @param realm the realm the credentials apply to. May be set - * to null if credenticals are applicable to - * any realm. - * @param scheme the authentication scheme the credentials apply to. - * May be set to null if credenticals are applicable to - * any authentication scheme. - * - * @since 3.0 - */ - public HttpAuthRealm(final String host, int port, - final String realm, final String scheme) - { - this.host = host; - this.port = port; - this.realm = realm; - this.scheme = scheme; - } - - /** Creates a new authentication realm token for the given - * host, port, realm, and any - * authentication scheme. + /** Creates a new HttpAuthRealm for the given domain and + * realm. * - * @param host the host the credentials apply to. May be set + * @param domain the domain the credentials apply to. May be set * to null if credenticals are applicable to - * any host. - * @param port the port the credentials apply to. May be set - * to negative value if credenticals are applicable to - * any port. + * any domain. * @param realm the realm the credentials apply to. May be set * to null if credenticals are applicable to * any realm. - * - * @since 3.0 + * */ - public HttpAuthRealm(final String host, int port, final String realm) { - this(host, port, realm, null); + public HttpAuthRealm(final String domain, final String realm) { + super(domain, ANY_PORT, realm, ANY_SCHEME); } - /** Creates a new authentication realm token for the given - * host, port, any realm name, and any - * authentication scheme. - * - * @param host the host the credentials apply to. May be set - * to null if credenticals are applicable to - * any host. - * @param port the port the credentials apply to. May be set - * to negative value if credenticals are applicable to - * any port. - * - * @since 3.0 - */ - public HttpAuthRealm(final String host, int port) { - this(host, port, null, null); - } - - /** Creates a new authentication realm token for the given - * host, realm, any port, and any authentication - * scheme. - * - * @param host the host the credentials apply to. May be set - * to null if credenticals are applicable to - * any host. - * @param realm the realm the credentials apply to. May be set - * to null if credenticals are applicable to - * any realm. - */ - public HttpAuthRealm(final String host, final String realm) { - this(host, -1, realm, null); - } - - /** - * Creates a new authentication realm token that matches any - * authentication realm. - * - * @since 3.0 - */ - public HttpAuthRealm() { - this(null, -1, null, null); - } - - /** - * Creates a copy of the given authentication realm token. - * - * @since 3.0 - */ - public HttpAuthRealm(final HttpAuthRealm token) { - this(token.host, token.port, token.realm, token.scheme); - } - - /** - * @return the host - * - * @since 3.0 - */ - public String getHost() { - return this.host; - } - - /** - * @return the port - * - * @since 3.0 - */ - public int getPort() { - return this.port; - } - - /** - * @return the realm name - * - * @since 3.0 - */ - public String getRealm() { - return this.realm; - } - - /** - * @return the scheme type - * - * @since 3.0 - */ - public String getScheme() { - return this.scheme; - } - - /** Determines if the given parameters match. Note that null acts as a - * wildcard so if either of the parameters are null, it is considered a match. - * - * @param p1 the parameter - * @param p2 the other parameter - * @return boolean true if the parameters match, otherwise false. - */ - private static boolean paramsMatchIgnoreCase(final String p1, final String p2) { - return p1 == null || p2 == null || p1.equalsIgnoreCase(p2); - } - - /** Determines if the given parameters match. Note that null acts as a - * wildcard so if either of the parameters are null, it is considered a match. - * - * @param p1 the parameter - * @param p2 the other parameter - * @return boolean true if the parameters match, otherwise false. - */ - private static boolean paramsMatch(final String p1, final String p2) { - return p1 == null || p2 == null || p1.equals(p2); - } - - /** Determines if the given parameters match. Note that negative value acts as a - * wildcard so if either of the parameters are negative, it is considered a match. - * - * @param p1 the parameter - * @param p2 the other parameter - * @return boolean true if the parameters match, otherwise false. - */ - private static boolean paramsMatch(int p1, int p2) { - return p1 < 0 || p2 < 0 || p1 == p2; - } - - /** - * @see java.lang.Object#equals(Object) - */ - public boolean equals(Object o) { - if (o == null) { - return false; - } - if (o == this) { - return true; - } - if (!(o instanceof HttpAuthRealm)) { - return super.equals(o); - } - HttpAuthRealm that = (HttpAuthRealm) o; - return - paramsMatchIgnoreCase(this.host, that.host) - && paramsMatch(this.port, that.port) - && paramsMatch(this.realm, that.realm) - && paramsMatchIgnoreCase(this.scheme, that.scheme); - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() { - StringBuffer buffer = new StringBuffer(); - if (this.scheme != null) { - buffer.append(this.scheme); - buffer.append(' '); - } - if (this.realm != null) { - buffer.append("authentication realm '"); - buffer.append(this.realm); - buffer.append("'"); - } else { - buffer.append("default authentication realm "); - } - if (this.host != null) { - buffer.append('@'); - buffer.append(this.host); - if (this.port >= 0) { - buffer.append(':'); - buffer.append(this.port); - } - } - return buffer.toString(); - } - /** - * @see java.lang.Object#hashCode() - */ - public int hashCode() { - return ((this.host != null) ? this.host.toLowerCase().hashCode() : 0) + - ((this.port >= 0) ? this.port : -1) + - ((this.realm != null) ? this.realm.hashCode() : 0) + - ((this.scheme != null) ? this.scheme.toLowerCase().hashCode() : 0); - } } Index: src/test/org/apache/commons/httpclient/TestWebappBasicAuth.java =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestWebappBasicAuth.java,v retrieving revision 1.16 diff -u -r1.16 TestWebappBasicAuth.java --- src/test/org/apache/commons/httpclient/TestWebappBasicAuth.java 12 May 2004 20:43:54 -0000 1.16 +++ src/test/org/apache/commons/httpclient/TestWebappBasicAuth.java 12 Jun 2004 17:26:29 -0000 @@ -1,5 +1,5 @@ /* - * $Header: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestWebappBasicAuth.java,v 1.16 2004/05/12 20:43:54 olegk Exp $ + * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestWebappBasicAuth.java,v 1.16 2004/05/12 20:43:54 olegk Exp $ * $Revision: 1.16 $ * $Date: 2004/05/12 20:43:54 $ * ==================================================================== @@ -33,7 +33,7 @@ import junit.framework.Test; import junit.framework.TestSuite; -import org.apache.commons.httpclient.auth.HttpAuthRealm; +import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.methods.HeadMethod; import org.apache.commons.httpclient.methods.PostMethod; @@ -80,7 +80,7 @@ public void testSimpleAuthGet() throws Exception { HttpClient client = createHttpClient(); client.getState().setCredentials( - new HttpAuthRealm(getHost(), getPort(), "BasicAuthServlet"), + new AuthScope(getHost(), getPort(), "BasicAuthServlet"), new UsernamePasswordCredentials("jakarta","commons")); GetMethod method = new GetMethod("/" + getWebappContext() + "/auth/basic"); @@ -110,7 +110,7 @@ public void testSimpleAuthPost() throws Exception { HttpClient client = createHttpClient(); client.getState().setCredentials( - new HttpAuthRealm(getHost(), getPort(), "BasicAuthServlet"), + new AuthScope(getHost(), getPort(), "BasicAuthServlet"), new UsernamePasswordCredentials("jakarta","commons")); PostMethod method = new PostMethod("/" + getWebappContext() + "/auth/basic"); method.setRequestBody(new NameValuePair[] { new NameValuePair("testing","one") } ); @@ -142,7 +142,7 @@ public void testSimpleAuthPut() throws Exception { HttpClient client = createHttpClient(); client.getState().setCredentials( - new HttpAuthRealm(getHost(), getPort(), "BasicAuthServlet"), + new AuthScope(getHost(), getPort(), "BasicAuthServlet"), new UsernamePasswordCredentials("jakarta","commons")); PutMethod method = new PutMethod("/" + getWebappContext() + "/auth/basic"); method.setRequestEntity(new StringRequestEntity("testing one two three")); @@ -184,7 +184,7 @@ assertTrue(method.getResponseBodyAsString().indexOf("

Not authorized.

") >= 0); client.getState().setCredentials( - new HttpAuthRealm(getHost(), getPort(), "BasicAuthServlet"), + new AuthScope(getHost(), getPort(), "BasicAuthServlet"), new UsernamePasswordCredentials("jakarta","commons")); method.recycle(); @@ -215,7 +215,7 @@ assertTrue(method.getResponseBodyAsString().indexOf("

Not authorized.

") >= 0); client.getState().setCredentials( - new HttpAuthRealm(getHost(), getPort(), "BasicAuthServlet"), + new AuthScope(getHost(), getPort(), "BasicAuthServlet"), new UsernamePasswordCredentials("bad","creds")); method.recycle(); Index: src/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.2 diff -u -r1.2 TestBasicAuth.java --- src/test/org/apache/commons/httpclient/auth/TestBasicAuth.java 25 Mar 2004 20:37:20 -0000 1.2 +++ src/test/org/apache/commons/httpclient/auth/TestBasicAuth.java 12 Jun 2004 17:26:30 -0000 @@ -1,5 +1,5 @@ /* - * $Header: /home/cvspublic/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/auth/TestBasicAuth.java,v 1.2 2004/03/25 20:37:20 olegk Exp $ + * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/auth/TestBasicAuth.java,v 1.2 2004/03/25 20:37:20 olegk Exp $ * $Revision: 1.2 $ * $Date: 2004/03/25 20:37:20 $ * ==================================================================== @@ -250,7 +250,7 @@ public void testBasicAuthenticationWithDefaultCreds() throws Exception { HttpState state = new HttpState(); - state.setCredentials(new HttpAuthRealm(), new UsernamePasswordCredentials("test", "test")); + state.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("test", "test")); this.client.setState(state); this.server.setHttpService(new BasicAuthService()); GetMethod httpget = new GetMethod("/test/"); @@ -274,11 +274,11 @@ public void testBasicAuthentication() throws Exception { HttpState state = new HttpState(); - HttpAuthRealm realm = new HttpAuthRealm( + AuthScope authscope = new AuthScope( this.server.getLocalAddress(), this.server.getLocalPort(), "test"); - state.setCredentials(realm, new UsernamePasswordCredentials("test", "test")); + state.setCredentials(authscope, new UsernamePasswordCredentials("test", "test")); this.client.setState(state); this.server.setHttpService(new BasicAuthService()); GetMethod httpget = new GetMethod("/test/"); @@ -302,11 +302,11 @@ public void testBasicAuthenticationWithInvalidCredentials() throws Exception { HttpState state = new HttpState(); - HttpAuthRealm realm = new HttpAuthRealm( + AuthScope authscope = new AuthScope( this.server.getLocalAddress(), this.server.getLocalPort(), "test"); - state.setCredentials(realm, new UsernamePasswordCredentials("test", "stuff")); + state.setCredentials(authscope, new UsernamePasswordCredentials("test", "stuff")); this.client.setState(state); this.server.setHttpService(new BasicAuthService()); GetMethod httpget = new GetMethod("/test/"); @@ -325,11 +325,11 @@ public void testBasicAuthenticationWithMutlipleRealms() throws Exception { HttpState state = new HttpState(); - HttpAuthRealm realm1 = new HttpAuthRealm( + AuthScope realm1 = new AuthScope( this.server.getLocalAddress(), this.server.getLocalPort(), "test"); - HttpAuthRealm realm2 = new HttpAuthRealm( + AuthScope realm2 = new AuthScope( this.server.getLocalAddress(), this.server.getLocalPort(), "test2"); @@ -380,7 +380,7 @@ public void testPreemptiveAuthorizationTrueWithCreds() throws Exception { HttpState state = new HttpState(); - state.setCredentials(new HttpAuthRealm(), new UsernamePasswordCredentials("test", "test")); + state.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("test", "test")); this.client.setState(state); this.client.getParams().setAuthenticationPreemptive(true); this.server.setHttpService(new BasicAuthService()); @@ -404,13 +404,35 @@ assertTrue(authstate.isPreemptive()); } + public void testPreemptiveAuthorizationTrueWithoutCreds() throws Exception { + HttpState state = new HttpState(); + this.client.setState(state); + this.client.getParams().setAuthenticationPreemptive(true); + this.server.setHttpService(new BasicAuthService()); + GetMethod httpget = new GetMethod("/test/"); + try { + this.client.executeMethod(httpget); + } finally { + httpget.releaseConnection(); + } + assertNotNull(httpget.getStatusLine()); + assertEquals(HttpStatus.SC_UNAUTHORIZED, httpget.getStatusLine().getStatusCode()); + Header auth = httpget.getRequestHeader("Authorization"); + assertNull(auth); + AuthState authstate = httpget.getHostAuthState(); + assertNotNull(authstate.getAuthScheme()); + assertTrue(authstate.getAuthScheme() instanceof BasicScheme); + assertNotNull(authstate.getRealm()); + assertFalse(authstate.isPreemptive()); + } + public void testBasicAuthenticationCaseInsensitivity() throws Exception { HttpState state = new HttpState(); - HttpAuthRealm realm = new HttpAuthRealm( + AuthScope authscope = new AuthScope( this.server.getLocalAddress(), this.server.getLocalPort(), "test"); - state.setCredentials(realm, new UsernamePasswordCredentials("test", "test")); + state.setCredentials(authscope, new UsernamePasswordCredentials("test", "test")); this.client.setState(state); this.server.setHttpService(new BasicAuthService3()); GetMethod httpget = new GetMethod("/test/"); Index: xdocs/authentication.xml =================================================================== RCS file: /home/cvspublic/jakarta-commons/httpclient/xdocs/authentication.xml,v retrieving revision 1.10 diff -u -r1.10 authentication.xml --- xdocs/authentication.xml 1 Jun 2004 20:57:59 -0000 1.10 +++ xdocs/authentication.xml 12 Jun 2004 17:26:31 -0000 @@ -21,9 +21,9 @@

HttpClient handles authenticating with servers almost transparently, the only thing a developer must do is actually provide the login credentials. These credentials are stored in the HttpState instance - and can be set or retrieved using the setCredentials(String realm, - String host, Credentials cred) and getCredentials(String realm, - String host) methods.

+ and can be set or retrieved using the setCredentials(AuthScope authscope, + Credentials cred) and getCredentials(AuthScope authscope) + methods.

Note: To set default Credentials for any realm that has not been explicitly specified, pass in null as the value of @@ -47,7 +47,7 @@ authentication mode ineffective.

Credentials defaultcreds = new UsernamePasswordCredentials("username", "password"); -client.getState().setCredentials(null, "myhost", defaultcreds); +client.getState().setCredentials(new AuthScope("myhost", 80, AuthScope.ANY_REALM), defaultcreds);

To enable preemptive authentication by default for all newly created HttpState's, a system property can be set, as shown below.

@@ -77,15 +77,15 @@ always specify the host and, when known, the realm the credentials are intended for.

- Setting credentials with null host and realm values is highly - discouraged in production applications. Doing this will result in the credentials - being sent for all authentication attempts (all requests in the case of - preemptive authentication). Use of this setting should be limited to debugging - only. + Setting credentials with AuthScope.ANY authentication scope (null value + for host and/or realm) is highly discouraged in production applications. Doing this + will result in the credentials being sent for all authentication attempts (all + requests in the case of preemptive authentication). Use of this setting should be + limited to debugging only.

// To be avoided unless in debug mode Credentials defaultcreds = new UsernamePasswordCredentials("username", "password"); -client.getState().setCredentials(null, null, defaultcreds); +client.getState().setCredentials(AuthScope.ANY, defaultcreds); @@ -94,8 +94,8 @@

Proxy authentication in HttpClient is almost identical to server authentication with the exception that the credentials for each are stored independantly. So for proxy authentication you must use - setProxyCredentials(String realm, Credentials cred) and - getProxyCredentials(String realm). As with server + setProxyCredentials(AuthScope authscope, Credentials cred) and + getProxyCredentials(AuthScope authscope). As with server authentication, passing null as the realm sets or returns the default credentials.