1. /*
  2. * $Header: /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: 1.6 $
  4. * $Date: 2004/05/13 04:02:00 $
  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. package org.apache.commons.httpclient.auth;
  30. import java.util.ArrayList;
  31. import java.util.HashMap;
  32. import java.util.List;
  33. import org.apache.commons.logging.Log;
  34. import org.apache.commons.logging.LogFactory;
  35. /**
  36. * Authentication policy class. The Authentication policy provides corresponding
  37. * authentication scheme interfrace for a given type of authorization challenge.
  38. * <p>The following specifications are provided:
  39. * <ul>
  40. * <li><tt>Basic</tt>: Basic authentication scheme as defined in RFC2617
  41. * (considered inherently insecure, but most widely supported)
  42. * <li><tt>Digest</tt>: Digest authentication scheme as defined in RFC2617
  43. * <li><tt>NTLM</tt>: The NTLM scheme is a proprietary Microsoft Windows
  44. * Authentication protocol (considered to be the most secure among
  45. * currently supported authentication schemes)
  46. * </ul>
  47. *
  48. * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
  49. *
  50. * @version $Revision: 1.6 $
  51. * @since 3.0
  52. */
  53. public abstract class AuthPolicy {
  54. private static final HashMap SCHEMES = new HashMap();
  55. private static final ArrayList SCHEME_LIST = new ArrayList();
  56. /**
  57. * The key used to look up the list of IDs of supported {@link AuthScheme
  58. * authentication schemes} in their order of preference. The scheme IDs are
  59. * stored in a {@link java.util.Collection} as {@link java.lang.String}s.
  60. *
  61. * <p>
  62. * If several schemes are returned in the <tt>WWW-Authenticate</tt>
  63. * or <tt>Proxy-Authenticate</tt> header, this parameter defines which
  64. * {@link AuthScheme authentication schemes} takes precedence over others.
  65. * The first item in the collection represents the most preferred
  66. * {@link AuthScheme authentication scheme}, the last item represents the ID
  67. * of the least preferred one.
  68. * </p>
  69. *
  70. * @see org.apache.commons.httpclient.params.DefaultHttpParams
  71. */
  72. public static final String AUTH_SCHEME_PRIORITY = "http.auth.scheme-priority";
  73. /**
  74. * The NTLM scheme is a proprietary Microsoft Windows Authentication
  75. * protocol (considered to be the most secure among currently supported
  76. * authentication schemes).
  77. */
  78. public static final String NTLM = "NTLM";
  79. /**
  80. * Digest authentication scheme as defined in RFC2617.
  81. */
  82. public static final String DIGEST = "Digest";
  83. /**
  84. * Basic authentication scheme as defined in RFC2617 (considered inherently
  85. * insecure, but most widely supported)
  86. */
  87. public static final String BASIC = "Basic";
  88. static {
  89. AuthPolicy.registerAuthScheme(NTLM, NTLMScheme.class);
  90. AuthPolicy.registerAuthScheme(DIGEST, DigestScheme.class);
  91. AuthPolicy.registerAuthScheme(BASIC, BasicScheme.class);
  92. }
  93. /** Log object. */
  94. protected static final Log LOG = LogFactory.getLog(AuthPolicy.class);
  95. /**
  96. * Registers a class implementing an {@link AuthScheme authentication scheme} with
  97. * the given identifier. If a class with the given ID already exists it will be overridden.
  98. * This ID is the same one used to retrieve the {@link AuthScheme authentication scheme}
  99. * from {@link #getAuthScheme(String)}.
  100. *
  101. * <p>
  102. * Please note that custom authentication preferences, if used, need to be updated accordingly
  103. * for the new {@link AuthScheme authentication scheme} to take effect.
  104. * </p>
  105. *
  106. * @param id the identifier for this scheme
  107. * @param clazz the class to register
  108. *
  109. * @see #getAuthScheme(String)
  110. * @see #AUTH_SCHEME_PRIORITY
  111. */
  112. public static synchronized void registerAuthScheme(final String id, Class clazz) {
  113. if (id == null) {
  114. throw new IllegalArgumentException("Id may not be null");
  115. }
  116. if (clazz == null) {
  117. throw new IllegalArgumentException("Authentication scheme class may not be null");
  118. }
  119. SCHEMES.put(id.toLowerCase(), clazz);
  120. SCHEME_LIST.add(id.toLowerCase());
  121. }
  122. /**
  123. * Unregisters the class implementing an {@link AuthScheme authentication scheme} with
  124. * the given ID.
  125. *
  126. * @param id the ID of the class to unregister
  127. */
  128. public static synchronized void unregisterAuthScheme(final String id) {
  129. if (id == null) {
  130. throw new IllegalArgumentException("Id may not be null");
  131. }
  132. SCHEMES.remove(id.toLowerCase());
  133. SCHEME_LIST.remove(id.toLowerCase());
  134. }
  135. /**
  136. * Gets the {@link AuthScheme authentication scheme} with the given ID.
  137. *
  138. * @param id the {@link AuthScheme authentication scheme} ID
  139. *
  140. * @return {@link AuthScheme authentication scheme}
  141. *
  142. * @throws IllegalStateException if a scheme with the ID cannot be found
  143. */
  144. public static synchronized AuthScheme getAuthScheme(final String id)
  145. throws IllegalStateException {
  146. if (id == null) {
  147. throw new IllegalArgumentException("Id may not be null");
  148. }
  149. Class clazz = (Class)SCHEMES.get(id.toLowerCase());
  150. if (clazz != null) {
  151. try {
  152. return (AuthScheme)clazz.newInstance();
  153. } catch (Exception e) {
  154. LOG.error("Error initializing authentication scheme: " + id, e);
  155. throw new IllegalStateException(id +
  156. " authentication scheme implemented by " +
  157. clazz.getName() + " could not be initialized");
  158. }
  159. } else {
  160. throw new IllegalStateException("Unsupported authentication scheme " + id);
  161. }
  162. }
  163. /**
  164. * Returns a list containing all registered {@link AuthScheme authentication
  165. * schemes} in their default order.
  166. *
  167. * @return {@link AuthScheme authentication scheme}
  168. */
  169. public static synchronized List getDefaultAuthPrefs() {
  170. return (List)SCHEME_LIST.clone();
  171. }
  172. }