View Javadoc

1   /*
2    * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//httpclient/src/java/org/apache/commons/httpclient/auth/AuthPolicy.java,v 1.6 2004/05/13 04:02:00 mbecke Exp $
3    * $Revision: 155418 $
4    * $Date: 2005-02-26 08:01:52 -0500 (Sat, 26 Feb 2005) $
5    *
6    * ====================================================================
7    *
8    *  Copyright 2002-2004 The Apache Software Foundation
9    *
10   *  Licensed under the Apache License, Version 2.0 (the "License");
11   *  you may not use this file except in compliance with the License.
12   *  You may obtain a copy of the License at
13   *
14   *      http://www.apache.org/licenses/LICENSE-2.0
15   *
16   *  Unless required by applicable law or agreed to in writing, software
17   *  distributed under the License is distributed on an "AS IS" BASIS,
18   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   *  See the License for the specific language governing permissions and
20   *  limitations under the License.
21   * ====================================================================
22   *
23   * This software consists of voluntary contributions made by many
24   * individuals on behalf of the Apache Software Foundation.  For more
25   * information on the Apache Software Foundation, please see
26   * <http://www.apache.org/>.
27   *
28   */
29  
30  package org.apache.commons.httpclient.auth;
31  
32  import java.util.ArrayList;
33  import java.util.HashMap;
34  import java.util.List;
35  
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  
39  /***
40   * Authentication policy class. The Authentication policy provides corresponding
41   * authentication scheme interfrace for a given type of authorization challenge. 
42   * <p>The following specifications are provided:
43   *  <ul>
44   *   <li><tt>Basic</tt>: Basic authentication scheme as defined in RFC2617
45   *           (considered inherently insecure, but most widely supported)
46   *   <li><tt>Digest</tt>: Digest authentication scheme as defined in RFC2617
47   *   <li><tt>NTLM</tt>: The NTLM scheme is a proprietary Microsoft Windows 
48   *           Authentication protocol (considered to be the most secure among
49   *           currently supported authentication schemes)
50   *  </ul>
51   * 
52   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
53   *
54   * @version $Revision: 155418 $
55   * @since 3.0
56   */
57  public abstract class AuthPolicy {
58  
59      private static final HashMap   SCHEMES     = new HashMap();
60      private static final ArrayList SCHEME_LIST = new ArrayList();
61      
62      /***
63       * The key used to look up the list of IDs of supported {@link AuthScheme 
64       * authentication schemes} in their order of preference. The scheme IDs are 
65       * stored in a {@link java.util.Collection} as {@link java.lang.String}s. 
66       * 
67       * <p>
68       * If several schemes are returned in the <tt>WWW-Authenticate</tt> 
69       * or <tt>Proxy-Authenticate</tt> header, this parameter defines which
70       * {@link AuthScheme authentication schemes} takes precedence over others.
71       * The first item in the collection represents the most preferred 
72       * {@link AuthScheme authentication scheme}, the last item represents the ID 
73       * of the least preferred one.
74       * </p>
75       * 
76       * @see org.apache.commons.httpclient.params.DefaultHttpParams
77       */
78      public static final String AUTH_SCHEME_PRIORITY = "http.auth.scheme-priority";
79  
80      /***
81       * The NTLM scheme is a proprietary Microsoft Windows Authentication 
82       * protocol (considered to be the most secure among currently supported 
83       * authentication schemes).
84       */
85      public static final String NTLM = "NTLM";
86      
87      /*** 
88       * Digest authentication scheme as defined in RFC2617.
89       */
90      public static final String DIGEST = "Digest";
91  
92      /*** 
93       * Basic authentication scheme as defined in RFC2617 (considered inherently
94       * insecure, but most widely supported)
95       */
96      public static final String BASIC = "Basic";
97      
98      static {
99          AuthPolicy.registerAuthScheme(NTLM,   NTLMScheme.class);
100         AuthPolicy.registerAuthScheme(DIGEST, DigestScheme.class);
101         AuthPolicy.registerAuthScheme(BASIC,  BasicScheme.class);
102     }
103     
104     /*** Log object. */
105     protected static final Log LOG = LogFactory.getLog(AuthPolicy.class);
106 
107     /***
108      * Registers a class implementing an {@link AuthScheme authentication scheme} with 
109      * the given identifier. If a class with the given ID already exists it will be overridden.  
110      * This ID is the same one used to retrieve the {@link AuthScheme authentication scheme} 
111      * from {@link #getAuthScheme(String)}.
112      * 
113      * <p>
114      * Please note that custom authentication preferences, if used, need to be updated accordingly 
115      * for the new {@link AuthScheme authentication scheme} to take effect.
116      * </p>    
117      * 
118      * @param id the identifier for this scheme
119      * @param clazz the class to register
120      * 
121      * @see #getAuthScheme(String)
122      * @see #AUTH_SCHEME_PRIORITY
123      */
124     public static synchronized void registerAuthScheme(final String id, Class clazz) {
125          if (id == null) {
126              throw new IllegalArgumentException("Id may not be null");
127          }
128         if (clazz == null) {
129             throw new IllegalArgumentException("Authentication scheme class may not be null");
130         }
131         SCHEMES.put(id.toLowerCase(), clazz);
132         SCHEME_LIST.add(id.toLowerCase());
133     }
134 
135     /***
136      * Unregisters the class implementing an {@link AuthScheme authentication scheme} with 
137      * the given ID.
138      * 
139      * @param id the ID of the class to unregister
140      */
141     public static synchronized void unregisterAuthScheme(final String id) {
142          if (id == null) {
143              throw new IllegalArgumentException("Id may not be null");
144          }
145         SCHEMES.remove(id.toLowerCase());
146         SCHEME_LIST.remove(id.toLowerCase());
147     }
148 
149     /***
150      * Gets the {@link AuthScheme authentication scheme} with the given ID.
151      * 
152      * @param id the {@link AuthScheme authentication scheme} ID
153      * 
154      * @return {@link AuthScheme authentication scheme}
155      * 
156      * @throws IllegalStateException if a scheme with the ID cannot be found
157      */
158     public static synchronized AuthScheme getAuthScheme(final String id) 
159         throws IllegalStateException {
160 
161         if (id == null) {
162             throw new IllegalArgumentException("Id may not be null");
163         }
164         Class clazz = (Class)SCHEMES.get(id.toLowerCase());
165         if (clazz != null) {
166             try {
167                 return (AuthScheme)clazz.newInstance();
168             } catch (Exception e) {
169                 LOG.error("Error initializing authentication scheme: " + id, e);
170                 throw new IllegalStateException(id + 
171                     " authentication scheme implemented by " +
172                     clazz.getName() + " could not be initialized");
173             }
174         } else {
175             throw new IllegalStateException("Unsupported authentication scheme " + id);
176         }
177     } 
178 
179     /***
180      * Returns a list containing all registered {@link AuthScheme authentication 
181      * schemes} in their default order.
182      * 
183      * @return {@link AuthScheme authentication scheme}
184      */
185     public static synchronized List getDefaultAuthPrefs() {
186         return (List)SCHEME_LIST.clone(); 
187     } 
188 }