olegk 2004/01/28 13:39:16
Modified: httpclient/src/java/org/apache/commons/httpclient
HttpMethodDirector.java
httpclient/src/java/org/apache/commons/httpclient/auth
AuthPolicy.java
Added: httpclient/src/examples AlternateAuthenticationExample.java
Log:
PR #15297 (Authenticator() - ability to perform alternate authentication)
Contributed by Oleg Kalnichevski
Reviewed by Ortwin Gluek & Michael Becke
Revision Changes Path
1.1
jakarta-commons/httpclient/src/examples/AlternateAuthenticationExample.java
Index: AlternateAuthenticationExample.java
===================================================================
/*
* $Header:
/home/cvs/jakarta-commons/httpclient/src/examples/AlternateAuthenticationExample.java,v
1.1 2004/01/28 21:39:15 olegk Exp $
* $Revision: 1.1 $
* $Date: 2004/01/28 21:39:15 $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "HttpClient", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthPolicy;
import org.apache.commons.httpclient.methods.GetMethod;
/**
* <p>A simple example that uses alternate authentication scheme selection
* if several authentication challenges are returned.
* </p>
*
* <p>Per default HttpClient picks the authentication challenge in the following
* order of preference: NTLM, Digest, Basic. In certain cases it may be desirable to
* force the use of a weaker authentication scheme.
* </p>
*
* @author Oleg Kalnichevski
*/
public class AlternateAuthenticationExample {
/**
* Constructor for BasicAuthenticatonExample.
*/
public AlternateAuthenticationExample() {
super();
}
public static void main(String[] args) throws Exception {
HttpClient client = new HttpClient();
client.getState().setCredentials("myrealm", "myhost",
new UsernamePasswordCredentials("username", "password"));
// Suppose the site supports several authetication schemes: NTLM and Basic
// Basic authetication is considered inherently insecure. Hence, NTLM
authentication
// is used per default
// This is to make HttpClient pick the Basic authentication scheme over NTLM
& Digest
List authPrefs = new ArrayList(3);
authPrefs.add(AuthPolicy.BASIC);
authPrefs.add(AuthPolicy.NTLM);
authPrefs.add(AuthPolicy.DIGEST);
client.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
GetMethod httpget = new
GetMethod("http://myhost/protected/auth-required.html");
try {
int status = client.executeMethod(httpget);
// print the status and response
System.out.println(httpget.getStatusLine());
System.out.println(httpget.getResponseBodyAsString());
} finally {
// release any connection resources used by the method
httpget.releaseConnection();
}
}
}
1.15 +13 -15
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.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- HttpMethodDirector.java 14 Jan 2004 18:59:27 -0000 1.14
+++ HttpMethodDirector.java 28 Jan 2004 21:39:16 -0000 1.15
@@ -64,9 +64,8 @@
package org.apache.commons.httpclient;
import java.io.IOException;
-import java.util.ArrayList;
+import java.util.Collection;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import org.apache.commons.httpclient.auth.AuthChallengeParser;
@@ -137,14 +136,6 @@
/** Whether preemtive proxy authentication is attempted */
private boolean proxyAuthPreemptive = false;
- //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,
final HostConfiguration hostConfiguration,
@@ -766,13 +757,20 @@
private AuthScheme processChallenge(final Map challenges)
throws MalformedChallengeException, AuthenticationException {
+
+ Collection authPrefs = (Collection) this.params.getParameter(
+
AuthPolicy.AUTH_SCHEME_PRIORITY);
+ if (authPrefs == null || authPrefs.isEmpty()) {
+ authPrefs = AuthPolicy.getDefaultAuthPrefs();
+ }
+
AuthScheme authscheme = null;
String challenge = null;
if (LOG.isDebugEnabled()) {
LOG.debug("Supported authentication schemes in the order of preference:
"
- + AUTH_PREFERENCES);
+ + authPrefs);
}
- Iterator item = AUTH_PREFERENCES.iterator();
+ Iterator item = authPrefs.iterator();
while (item.hasNext()) {
String id = (String) item.next();
challenge = (String) challenges.get(id.toLowerCase());
1.2 +49 -12
jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthPolicy.java
Index: AuthPolicy.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthPolicy.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AuthPolicy.java 10 Dec 2003 21:37:42 -0000 1.1
+++ AuthPolicy.java 28 Jan 2004 21:39:16 -0000 1.2
@@ -63,9 +63,9 @@
package org.apache.commons.httpclient.auth;
-import java.util.Collections;
+import java.util.ArrayList;
import java.util.HashMap;
-import java.util.Map;
+import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -90,9 +90,28 @@
*/
public abstract class AuthPolicy {
- private static Map SCHEMES = Collections.synchronizedMap(new HashMap());
+ private static final HashMap SCHEMES = new HashMap();
+ private static final ArrayList SCHEME_LIST = new ArrayList();
/**
+ * The key used to look up the list of IDs of supported [EMAIL PROTECTED]
AuthScheme
+ * authentication schemes} in their order of preference. The scheme IDs are
+ * stored in a [EMAIL PROTECTED] Collection} as [EMAIL PROTECTED]
java.lang.String}s.
+ *
+ * <p>
+ * If several schemes are returned in the <tt>WWW-Authenticate</tt>
+ * or <tt>Proxy-Authenticate</tt> header, this parameter defines which
+ * [EMAIL PROTECTED] AuthScheme authentication schemes} takes precedence over
others.
+ * The first item in the collection represents the most preferred
+ * [EMAIL PROTECTED] AuthScheme authentication scheme}, the last item
represents the ID
+ * of the least preferred one.
+ * </p>
+ *
+ * @see org.apache.commons.httpclient.params.DefaultHttpParams
+ */
+ public static final String AUTH_SCHEME_PRIORITY = "http.auth.scheme-priority";
+
+ /**
* The NTLM scheme is a proprietary Microsoft Windows Authentication
* protocol (considered to be the most secure among currently supported
* authentication schemes).
@@ -111,9 +130,9 @@
public static final String BASIC = "Basic";
static {
- AuthPolicy.registerAuthScheme(BASIC, BasicScheme.class);
+ AuthPolicy.registerAuthScheme(NTLM, NTLMScheme.class);
AuthPolicy.registerAuthScheme(DIGEST, DigestScheme.class);
- AuthPolicy.registerAuthScheme(NTLM, NTLMScheme.class);
+ AuthPolicy.registerAuthScheme(BASIC, BasicScheme.class);
}
/** Log object. */
@@ -125,12 +144,18 @@
* This ID is the same one used to retrieve the [EMAIL PROTECTED] AuthScheme
authentication scheme}
* from [EMAIL PROTECTED] #getAuthScheme(String)}.
*
+ * <p>
+ * Please note that custom authentication preferences, if used, need to be
updated accordingly
+ * for the new [EMAIL PROTECTED] AuthScheme authentication scheme} to take
effect.
+ * </p>
+ *
* @param id the identifier for this scheme
* @param clazz the class to register
*
* @see #getAuthScheme(String)
+ * @see #AUTH_SCHEME_PRIORITY
*/
- public static void registerAuthScheme(final String id, Class clazz) {
+ public static synchronized void registerAuthScheme(final String id, Class
clazz) {
if (id == null) {
throw new IllegalArgumentException("Id may not be null");
}
@@ -138,6 +163,7 @@
throw new IllegalArgumentException("Authentication scheme class may not
be null");
}
SCHEMES.put(id.toLowerCase(), clazz);
+ SCHEME_LIST.add(id.toLowerCase());
}
/**
@@ -146,11 +172,12 @@
*
* @param id the ID of the class to unregister
*/
- public static void unregisterAuthScheme(final String id) {
+ public static synchronized void unregisterAuthScheme(final String id) {
if (id == null) {
throw new IllegalArgumentException("Id may not be null");
}
SCHEMES.remove(id.toLowerCase());
+ SCHEME_LIST.remove(id.toLowerCase());
}
/**
@@ -162,7 +189,7 @@
*
* @throws IllegalStateException if a scheme with the ID cannot be found
*/
- public static AuthScheme getAuthScheme(final String id)
+ public static synchronized AuthScheme getAuthScheme(final String id)
throws IllegalStateException {
if (id == null) {
@@ -181,5 +208,15 @@
} else {
throw new IllegalStateException("Unsupported authentication scheme " +
id);
}
+ }
+
+ /**
+ * Returns a list containing all registered [EMAIL PROTECTED] AuthScheme
authentication
+ * schemes} in their default order.
+ *
+ * @return [EMAIL PROTECTED] AuthScheme authentication scheme}
+ */
+ public static synchronized List getDefaultAuthPrefs() {
+ return (List)SCHEME_LIST.clone();
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]