Save This Page
Home » openjdk-7 » javax.security » auth » login » [javadoc | source]
    1   /*
    2    * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.security.auth.login;
   27   
   28   import javax.security.auth.AuthPermission;
   29   
   30   import java.io;
   31   import java.util;
   32   import java.net.URI;
   33   import java.security.AccessController;
   34   import java.security.PrivilegedAction;
   35   import java.security.PrivilegedExceptionAction;
   36   import java.security.PrivilegedActionException;
   37   import java.security.NoSuchAlgorithmException;
   38   import java.security.NoSuchProviderException;
   39   import java.security.Provider;
   40   import java.security.Security;
   41   import java.security.SecurityPermission;
   42   
   43   import sun.security.jca.GetInstance;
   44   
   45   /**
   46    * A Configuration object is responsible for specifying which LoginModules
   47    * should be used for a particular application, and in what order the
   48    * LoginModules should be invoked.
   49    *
   50    * <p> A login configuration contains the following information.
   51    * Note that this example only represents the default syntax for the
   52    * <code>Configuration</code>.  Subclass implementations of this class
   53    * may implement alternative syntaxes and may retrieve the
   54    * <code>Configuration</code> from any source such as files, databases,
   55    * or servers.
   56    *
   57    * <pre>
   58    *      Name {
   59    *            ModuleClass  Flag    ModuleOptions;
   60    *            ModuleClass  Flag    ModuleOptions;
   61    *            ModuleClass  Flag    ModuleOptions;
   62    *      };
   63    *      Name {
   64    *            ModuleClass  Flag    ModuleOptions;
   65    *            ModuleClass  Flag    ModuleOptions;
   66    *      };
   67    *      other {
   68    *            ModuleClass  Flag    ModuleOptions;
   69    *            ModuleClass  Flag    ModuleOptions;
   70    *      };
   71    * </pre>
   72    *
   73    * <p> Each entry in the <code>Configuration</code> is indexed via an
   74    * application name, <i>Name</i>, and contains a list of
   75    * LoginModules configured for that application.  Each <code>LoginModule</code>
   76    * is specified via its fully qualified class name.
   77    * Authentication proceeds down the module list in the exact order specified.
   78    * If an application does not have specific entry,
   79    * it defaults to the specific entry for "<i>other</i>".
   80    *
   81    * <p> The <i>Flag</i> value controls the overall behavior as authentication
   82    * proceeds down the stack.  The following represents a description of the
   83    * valid values for <i>Flag</i> and their respective semantics:
   84    *
   85    * <pre>
   86    *      1) Required     - The <code>LoginModule</code> is required to succeed.
   87    *                      If it succeeds or fails, authentication still continues
   88    *                      to proceed down the <code>LoginModule</code> list.
   89    *
   90    *      2) Requisite    - The <code>LoginModule</code> is required to succeed.
   91    *                      If it succeeds, authentication continues down the
   92    *                      <code>LoginModule</code> list.  If it fails,
   93    *                      control immediately returns to the application
   94    *                      (authentication does not proceed down the
   95    *                      <code>LoginModule</code> list).
   96    *
   97    *      3) Sufficient   - The <code>LoginModule</code> is not required to
   98    *                      succeed.  If it does succeed, control immediately
   99    *                      returns to the application (authentication does not
  100    *                      proceed down the <code>LoginModule</code> list).
  101    *                      If it fails, authentication continues down the
  102    *                      <code>LoginModule</code> list.
  103    *
  104    *      4) Optional     - The <code>LoginModule</code> is not required to
  105    *                      succeed.  If it succeeds or fails,
  106    *                      authentication still continues to proceed down the
  107    *                      <code>LoginModule</code> list.
  108    * </pre>
  109    *
  110    * <p> The overall authentication succeeds only if all <i>Required</i> and
  111    * <i>Requisite</i> LoginModules succeed.  If a <i>Sufficient</i>
  112    * <code>LoginModule</code> is configured and succeeds,
  113    * then only the <i>Required</i> and <i>Requisite</i> LoginModules prior to
  114    * that <i>Sufficient</i> <code>LoginModule</code> need to have succeeded for
  115    * the overall authentication to succeed. If no <i>Required</i> or
  116    * <i>Requisite</i> LoginModules are configured for an application,
  117    * then at least one <i>Sufficient</i> or <i>Optional</i>
  118    * <code>LoginModule</code> must succeed.
  119    *
  120    * <p> <i>ModuleOptions</i> is a space separated list of
  121    * <code>LoginModule</code>-specific values which are passed directly to
  122    * the underlying LoginModules.  Options are defined by the
  123    * <code>LoginModule</code> itself, and control the behavior within it.
  124    * For example, a <code>LoginModule</code> may define options to support
  125    * debugging/testing capabilities.  The correct way to specify options in the
  126    * <code>Configuration</code> is by using the following key-value pairing:
  127    * <i>debug="true"</i>.  The key and value should be separated by an
  128    * 'equals' symbol, and the value should be surrounded by double quotes.
  129    * If a String in the form, ${system.property}, occurs in the value,
  130    * it will be expanded to the value of the system property.
  131    * Note that there is no limit to the number of
  132    * options a <code>LoginModule</code> may define.
  133    *
  134    * <p> The following represents an example <code>Configuration</code> entry
  135    * based on the syntax above:
  136    *
  137    * <pre>
  138    * Login {
  139    *   com.sun.security.auth.module.UnixLoginModule required;
  140    *   com.sun.security.auth.module.Krb5LoginModule optional
  141    *                   useTicketCache="true"
  142    *                   ticketCache="${user.home}${/}tickets";
  143    * };
  144    * </pre>
  145    *
  146    * <p> This <code>Configuration</code> specifies that an application named,
  147    * "Login", requires users to first authenticate to the
  148    * <i>com.sun.security.auth.module.UnixLoginModule</i>, which is
  149    * required to succeed.  Even if the <i>UnixLoginModule</i>
  150    * authentication fails, the
  151    * <i>com.sun.security.auth.module.Krb5LoginModule</i>
  152    * still gets invoked.  This helps hide the source of failure.
  153    * Since the <i>Krb5LoginModule</i> is <i>Optional</i>, the overall
  154    * authentication succeeds only if the <i>UnixLoginModule</i>
  155    * (<i>Required</i>) succeeds.
  156    *
  157    * <p> Also note that the LoginModule-specific options,
  158    * <i>useTicketCache="true"</i> and
  159    * <i>ticketCache=${user.home}${/}tickets"</i>,
  160    * are passed to the <i>Krb5LoginModule</i>.
  161    * These options instruct the <i>Krb5LoginModule</i> to
  162    * use the ticket cache at the specified location.
  163    * The system properties, <i>user.home</i> and <i>/</i>
  164    * (file.separator), are expanded to their respective values.
  165    *
  166    * <p> There is only one Configuration object installed in the runtime at any
  167    * given time.  A Configuration object can be installed by calling the
  168    * <code>setConfiguration</code> method.  The installed Configuration object
  169    * can be obtained by calling the <code>getConfiguration</code> method.
  170    *
  171    * <p> If no Configuration object has been installed in the runtime, a call to
  172    * <code>getConfiguration</code> installs an instance of the default
  173    * Configuration implementation (a default subclass implementation of this
  174    * abstract class).
  175    * The default Configuration implementation can be changed by setting the value
  176    * of the "login.configuration.provider" security property (in the Java
  177    * security properties file) to the fully qualified name of the desired
  178    * Configuration subclass implementation.  The Java security properties file
  179    * is located in the file named &lt;JAVA_HOME&gt;/lib/security/java.security.
  180    * &lt;JAVA_HOME&gt; refers to the value of the java.home system property,
  181    * and specifies the directory where the JRE is installed.
  182    *
  183    * <p> Application code can directly subclass Configuration to provide a custom
  184    * implementation.  In addition, an instance of a Configuration object can be
  185    * constructed by invoking one of the <code>getInstance</code> factory methods
  186    * with a standard type.  The default policy type is "JavaLoginConfig".
  187    * See Appendix A in the
  188    * <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
  189    * Java Cryptography Architecture API Specification &amp; Reference </a>
  190    * for a list of standard Configuration types.
  191    *
  192    * @see javax.security.auth.login.LoginContext
  193    */
  194   public abstract class Configuration {
  195   
  196       private static Configuration configuration;
  197       private static ClassLoader contextClassLoader;
  198   
  199       static {
  200           contextClassLoader = AccessController.doPrivileged
  201                   (new PrivilegedAction<ClassLoader>() {
  202                   public ClassLoader run() {
  203                       return Thread.currentThread().getContextClassLoader();
  204                   }
  205           });
  206       };
  207   
  208       private static void checkPermission(String type) {
  209           SecurityManager sm = System.getSecurityManager();
  210           if (sm != null) {
  211               sm.checkPermission(new AuthPermission
  212                                   ("createLoginConfiguration." + type));
  213           }
  214       }
  215   
  216       /**
  217        * Sole constructor.  (For invocation by subclass constructors, typically
  218        * implicit.)
  219        */
  220       protected Configuration() { }
  221   
  222       /**
  223        * Get the installed login Configuration.
  224        *
  225        * <p>
  226        *
  227        * @return the login Configuration.  If a Configuration object was set
  228        *          via the <code>Configuration.setConfiguration</code> method,
  229        *          then that object is returned.  Otherwise, a default
  230        *          Configuration object is returned.
  231        *
  232        * @exception SecurityException if the caller does not have permission
  233        *                          to retrieve the Configuration.
  234        *
  235        * @see #setConfiguration
  236        */
  237       public static synchronized Configuration getConfiguration() {
  238   
  239           SecurityManager sm = System.getSecurityManager();
  240           if (sm != null)
  241               sm.checkPermission(new AuthPermission("getLoginConfiguration"));
  242   
  243           if (configuration == null) {
  244               String config_class = null;
  245               config_class = AccessController.doPrivileged
  246                   (new PrivilegedAction<String>() {
  247                   public String run() {
  248                       return java.security.Security.getProperty
  249                                   ("login.configuration.provider");
  250                   }
  251               });
  252               if (config_class == null) {
  253                   config_class = "com.sun.security.auth.login.ConfigFile";
  254               }
  255   
  256               try {
  257                   final String finalClass = config_class;
  258                   configuration = AccessController.doPrivileged
  259                       (new PrivilegedExceptionAction<Configuration>() {
  260                       public Configuration run() throws ClassNotFoundException,
  261                                           InstantiationException,
  262                                           IllegalAccessException {
  263                           return (Configuration)Class.forName
  264                                   (finalClass,
  265                                   true,
  266                                   contextClassLoader).newInstance();
  267                       }
  268                   });
  269               } catch (PrivilegedActionException e) {
  270                   Exception ee = e.getException();
  271                   if (ee instanceof InstantiationException) {
  272                       throw (SecurityException) new
  273                           SecurityException
  274                                   ("Configuration error:" +
  275                                    ee.getCause().getMessage() +
  276                                    "\n").initCause(ee.getCause());
  277                   } else {
  278                       throw (SecurityException) new
  279                           SecurityException
  280                                   ("Configuration error: " +
  281                                    ee.toString() +
  282                                    "\n").initCause(ee);
  283                   }
  284               }
  285           }
  286           return configuration;
  287       }
  288   
  289       /**
  290        * Set the login <code>Configuration</code>.
  291        *
  292        * <p>
  293        *
  294        * @param configuration the new <code>Configuration</code>
  295        *
  296        * @exception SecurityException if the current thread does not have
  297        *                  Permission to set the <code>Configuration</code>.
  298        *
  299        * @see #getConfiguration
  300        */
  301       public static void setConfiguration(Configuration configuration) {
  302           SecurityManager sm = System.getSecurityManager();
  303           if (sm != null)
  304               sm.checkPermission(new AuthPermission("setLoginConfiguration"));
  305           Configuration.configuration = configuration;
  306       }
  307   
  308       /**
  309        * Returns a Configuration object of the specified type.
  310        *
  311        * <p> This method traverses the list of registered security providers,
  312        * starting with the most preferred Provider.
  313        * A new Configuration object encapsulating the
  314        * ConfigurationSpi implementation from the first
  315        * Provider that supports the specified type is returned.
  316        *
  317        * <p> Note that the list of registered providers may be retrieved via
  318        * the {@link Security#getProviders() Security.getProviders()} method.
  319        *
  320        * @param type the specified Configuration type.  See Appendix A in the
  321        *    <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
  322        *    Java Cryptography Architecture API Specification &amp; Reference </a>
  323        *    for a list of standard Configuration types.
  324        *
  325        * @param params parameters for the Configuration, which may be null.
  326        *
  327        * @return the new Configuration object.
  328        *
  329        * @exception SecurityException if the caller does not have permission
  330        *          to get a Configuration instance for the specified type.
  331        *
  332        * @exception NullPointerException if the specified type is null.
  333        *
  334        * @exception IllegalArgumentException if the specified parameters
  335        *          are not understood by the ConfigurationSpi implementation
  336        *          from the selected Provider.
  337        *
  338        * @exception NoSuchAlgorithmException if no Provider supports a
  339        *          ConfigurationSpi implementation for the specified type.
  340        *
  341        * @see Provider
  342        * @since 1.6
  343        */
  344       public static Configuration getInstance(String type,
  345                                   Configuration.Parameters params)
  346                   throws NoSuchAlgorithmException {
  347   
  348           checkPermission(type);
  349           try {
  350               GetInstance.Instance instance = GetInstance.getInstance
  351                                                           ("Configuration",
  352                                                           ConfigurationSpi.class,
  353                                                           type,
  354                                                           params);
  355               return new ConfigDelegate((ConfigurationSpi)instance.impl,
  356                                                           instance.provider,
  357                                                           type,
  358                                                           params);
  359           } catch (NoSuchAlgorithmException nsae) {
  360               return handleException (nsae);
  361           }
  362       }
  363   
  364       /**
  365        * Returns a Configuration object of the specified type.
  366        *
  367        * <p> A new Configuration object encapsulating the
  368        * ConfigurationSpi implementation from the specified provider
  369        * is returned.   The specified provider must be registered
  370        * in the provider list.
  371        *
  372        * <p> Note that the list of registered providers may be retrieved via
  373        * the {@link Security#getProviders() Security.getProviders()} method.
  374        *
  375        * @param type the specified Configuration type.  See Appendix A in the
  376        *    <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
  377        *    Java Cryptography Architecture API Specification &amp; Reference </a>
  378        *    for a list of standard Configuration types.
  379        *
  380        * @param params parameters for the Configuration, which may be null.
  381        *
  382        * @param provider the provider.
  383        *
  384        * @return the new Configuration object.
  385        *
  386        * @exception SecurityException if the caller does not have permission
  387        *          to get a Configuration instance for the specified type.
  388        *
  389        * @exception NullPointerException if the specified type is null.
  390        *
  391        * @exception IllegalArgumentException if the specified provider
  392        *          is null or empty,
  393        *          or if the specified parameters are not understood by
  394        *          the ConfigurationSpi implementation from the specified provider.
  395        *
  396        * @exception NoSuchProviderException if the specified provider is not
  397        *          registered in the security provider list.
  398        *
  399        * @exception NoSuchAlgorithmException if the specified provider does not
  400        *          support a ConfigurationSpi implementation for the specified
  401        *          type.
  402        *
  403        * @see Provider
  404        * @since 1.6
  405        */
  406       public static Configuration getInstance(String type,
  407                                   Configuration.Parameters params,
  408                                   String provider)
  409                   throws NoSuchProviderException, NoSuchAlgorithmException {
  410   
  411           if (provider == null || provider.length() == 0) {
  412               throw new IllegalArgumentException("missing provider");
  413           }
  414   
  415           checkPermission(type);
  416           try {
  417               GetInstance.Instance instance = GetInstance.getInstance
  418                                                           ("Configuration",
  419                                                           ConfigurationSpi.class,
  420                                                           type,
  421                                                           params,
  422                                                           provider);
  423               return new ConfigDelegate((ConfigurationSpi)instance.impl,
  424                                                           instance.provider,
  425                                                           type,
  426                                                           params);
  427           } catch (NoSuchAlgorithmException nsae) {
  428               return handleException (nsae);
  429           }
  430       }
  431   
  432       /**
  433        * Returns a Configuration object of the specified type.
  434        *
  435        * <p> A new Configuration object encapsulating the
  436        * ConfigurationSpi implementation from the specified Provider
  437        * object is returned.  Note that the specified Provider object
  438        * does not have to be registered in the provider list.
  439        *
  440        * @param type the specified Configuration type.  See Appendix A in the
  441        *    <a href="../../../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
  442        *    Java Cryptography Architecture API Specification &amp; Reference </a>
  443        *    for a list of standard Configuration types.
  444        *
  445        * @param params parameters for the Configuration, which may be null.
  446        *
  447        * @param provider the Provider.
  448        *
  449        * @return the new Configuration object.
  450        *
  451        * @exception SecurityException if the caller does not have permission
  452        *          to get a Configuration instance for the specified type.
  453        *
  454        * @exception NullPointerException if the specified type is null.
  455        *
  456        * @exception IllegalArgumentException if the specified Provider is null,
  457        *          or if the specified parameters are not understood by
  458        *          the ConfigurationSpi implementation from the specified Provider.
  459        *
  460        * @exception NoSuchAlgorithmException if the specified Provider does not
  461        *          support a ConfigurationSpi implementation for the specified
  462        *          type.
  463        *
  464        * @see Provider
  465        * @since 1.6
  466        */
  467       public static Configuration getInstance(String type,
  468                                   Configuration.Parameters params,
  469                                   Provider provider)
  470                   throws NoSuchAlgorithmException {
  471   
  472           if (provider == null) {
  473               throw new IllegalArgumentException("missing provider");
  474           }
  475   
  476           checkPermission(type);
  477           try {
  478               GetInstance.Instance instance = GetInstance.getInstance
  479                                                           ("Configuration",
  480                                                           ConfigurationSpi.class,
  481                                                           type,
  482                                                           params,
  483                                                           provider);
  484               return new ConfigDelegate((ConfigurationSpi)instance.impl,
  485                                                           instance.provider,
  486                                                           type,
  487                                                           params);
  488           } catch (NoSuchAlgorithmException nsae) {
  489               return handleException (nsae);
  490           }
  491       }
  492   
  493       private static Configuration handleException(NoSuchAlgorithmException nsae)
  494                   throws NoSuchAlgorithmException {
  495           Throwable cause = nsae.getCause();
  496           if (cause instanceof IllegalArgumentException) {
  497               throw (IllegalArgumentException)cause;
  498           }
  499           throw nsae;
  500       }
  501   
  502       /**
  503        * Return the Provider of this Configuration.
  504        *
  505        * <p> This Configuration instance will only have a Provider if it
  506        * was obtained via a call to <code>Configuration.getInstance</code>.
  507        * Otherwise this method returns null.
  508        *
  509        * @return the Provider of this Configuration, or null.
  510        *
  511        * @since 1.6
  512        */
  513       public Provider getProvider() {
  514           return null;
  515       }
  516   
  517       /**
  518        * Return the type of this Configuration.
  519        *
  520        * <p> This Configuration instance will only have a type if it
  521        * was obtained via a call to <code>Configuration.getInstance</code>.
  522        * Otherwise this method returns null.
  523        *
  524        * @return the type of this Configuration, or null.
  525        *
  526        * @since 1.6
  527        */
  528       public String getType() {
  529           return null;
  530       }
  531   
  532       /**
  533        * Return Configuration parameters.
  534        *
  535        * <p> This Configuration instance will only have parameters if it
  536        * was obtained via a call to <code>Configuration.getInstance</code>.
  537        * Otherwise this method returns null.
  538        *
  539        * @return Configuration parameters, or null.
  540        *
  541        * @since 1.6
  542        */
  543       public Configuration.Parameters getParameters() {
  544           return null;
  545       }
  546   
  547       /**
  548        * Retrieve the AppConfigurationEntries for the specified <i>name</i>
  549        * from this Configuration.
  550        *
  551        * <p>
  552        *
  553        * @param name the name used to index the Configuration.
  554        *
  555        * @return an array of AppConfigurationEntries for the specified <i>name</i>
  556        *          from this Configuration, or null if there are no entries
  557        *          for the specified <i>name</i>
  558        */
  559       public abstract AppConfigurationEntry[] getAppConfigurationEntry
  560                                                           (String name);
  561   
  562       /**
  563        * Refresh and reload the Configuration.
  564        *
  565        * <p> This method causes this Configuration object to refresh/reload its
  566        * contents in an implementation-dependent manner.
  567        * For example, if this Configuration object stores its entries in a file,
  568        * calling <code>refresh</code> may cause the file to be re-read.
  569        *
  570        * <p> The default implementation of this method does nothing.
  571        * This method should be overridden if a refresh operation is supported
  572        * by the implementation.
  573        *
  574        * @exception SecurityException if the caller does not have permission
  575        *                          to refresh its Configuration.
  576        */
  577       public void refresh() { }
  578   
  579       /**
  580        * This subclass is returned by the getInstance calls.  All Configuration
  581        * calls are delegated to the underlying ConfigurationSpi.
  582        */
  583       private static class ConfigDelegate extends Configuration {
  584   
  585           private ConfigurationSpi spi;
  586           private Provider p;
  587           private String type;
  588           private Configuration.Parameters params;
  589   
  590           private ConfigDelegate(ConfigurationSpi spi, Provider p,
  591                           String type, Configuration.Parameters params) {
  592               this.spi = spi;
  593               this.p = p;
  594               this.type = type;
  595               this.params = params;
  596           }
  597   
  598           public String getType() { return type; }
  599   
  600           public Configuration.Parameters getParameters() { return params; }
  601   
  602           public Provider getProvider() { return p; }
  603   
  604           public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
  605               return spi.engineGetAppConfigurationEntry(name);
  606           }
  607   
  608           public void refresh() {
  609               spi.engineRefresh();
  610           }
  611       }
  612   
  613       /**
  614        * This represents a marker interface for Configuration parameters.
  615        *
  616        * @since 1.6
  617        */
  618       public static interface Parameters { }
  619   }

Save This Page
Home » openjdk-7 » javax.security » auth » login » [javadoc | source]