Package javax.security.auth.login

Source Code of javax.security.auth.login.Configuration$Parameters

/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/

package javax.security.auth.login;

import javax.security.auth.AuthPermission;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Provider;
import java.security.Security;
import java.util.Objects;

import sun.security.jca.GetInstance;

/**
* A Configuration object is responsible for specifying which LoginModules
* should be used for a particular application, and in what order the
* LoginModules should be invoked.
*
* <p> A login configuration contains the following information.
* Note that this example only represents the default syntax for the
* {@code Configuration}.  Subclass implementations of this class
* may implement alternative syntaxes and may retrieve the
* {@code Configuration} from any source such as files, databases,
* or servers.
*
* <pre>
*      Name {
*            ModuleClass  Flag    ModuleOptions;
*            ModuleClass  Flag    ModuleOptions;
*            ModuleClass  Flag    ModuleOptions;
*      };
*      Name {
*            ModuleClass  Flag    ModuleOptions;
*            ModuleClass  Flag    ModuleOptions;
*      };
*      other {
*            ModuleClass  Flag    ModuleOptions;
*            ModuleClass  Flag    ModuleOptions;
*      };
* </pre>
*
* <p> Each entry in the {@code Configuration} is indexed via an
* application name, <i>Name</i>, and contains a list of
* LoginModules configured for that application.  Each {@code LoginModule}
* is specified via its fully qualified class name.
* Authentication proceeds down the module list in the exact order specified.
* If an application does not have a specific entry,
* it defaults to the specific entry for "<i>other</i>".
*
* <p> The <i>Flag</i> value controls the overall behavior as authentication
* proceeds down the stack.  The following represents a description of the
* valid values for <i>Flag</i> and their respective semantics:
*
* <pre>
*      1) Required     - The {@code LoginModule} is required to succeed.
*                      If it succeeds or fails, authentication still continues
*                      to proceed down the {@code LoginModule} list.
*
*      2) Requisite    - The {@code LoginModule} is required to succeed.
*                      If it succeeds, authentication continues down the
*                      {@code LoginModule} list.  If it fails,
*                      control immediately returns to the application
*                      (authentication does not proceed down the
*                      {@code LoginModule} list).
*
*      3) Sufficient   - The {@code LoginModule} is not required to
*                      succeed.  If it does succeed, control immediately
*                      returns to the application (authentication does not
*                      proceed down the {@code LoginModule} list).
*                      If it fails, authentication continues down the
*                      {@code LoginModule} list.
*
*      4) Optional     - The {@code LoginModule} is not required to
*                      succeed.  If it succeeds or fails,
*                      authentication still continues to proceed down the
*                      {@code LoginModule} list.
* </pre>
*
* <p> The overall authentication succeeds only if all <i>Required</i> and
* <i>Requisite</i> LoginModules succeed.  If a <i>Sufficient</i>
* {@code LoginModule} is configured and succeeds,
* then only the <i>Required</i> and <i>Requisite</i> LoginModules prior to
* that <i>Sufficient</i> {@code LoginModule} need to have succeeded for
* the overall authentication to succeed. If no <i>Required</i> or
* <i>Requisite</i> LoginModules are configured for an application,
* then at least one <i>Sufficient</i> or <i>Optional</i>
* {@code LoginModule} must succeed.
*
* <p> <i>ModuleOptions</i> is a space separated list of
* {@code LoginModule}-specific values which are passed directly to
* the underlying LoginModules.  Options are defined by the
* {@code LoginModule} itself, and control the behavior within it.
* For example, a {@code LoginModule} may define options to support
* debugging/testing capabilities.  The correct way to specify options in the
* {@code Configuration} is by using the following key-value pairing:
* <i>debug="true"</i>.  The key and value should be separated by an
* 'equals' symbol, and the value should be surrounded by double quotes.
* If a String in the form, ${system.property}, occurs in the value,
* it will be expanded to the value of the system property.
* Note that there is no limit to the number of
* options a {@code LoginModule} may define.
*
* <p> The following represents an example {@code Configuration} entry
* based on the syntax above:
*
* <pre>
* Login {
*   com.sun.security.auth.module.UnixLoginModule required;
*   com.sun.security.auth.module.Krb5LoginModule optional
*                   useTicketCache="true"
*                   ticketCache="${user.home}${/}tickets";
* };
* </pre>
*
* <p> This {@code Configuration} specifies that an application named,
* "Login", requires users to first authenticate to the
* <i>com.sun.security.auth.module.UnixLoginModule</i>, which is
* required to succeed.  Even if the <i>UnixLoginModule</i>
* authentication fails, the
* <i>com.sun.security.auth.module.Krb5LoginModule</i>
* still gets invoked.  This helps hide the source of failure.
* Since the <i>Krb5LoginModule</i> is <i>Optional</i>, the overall
* authentication succeeds only if the <i>UnixLoginModule</i>
* (<i>Required</i>) succeeds.
*
* <p> Also note that the LoginModule-specific options,
* <i>useTicketCache="true"</i> and
* <i>ticketCache=${user.home}${/}tickets"</i>,
* are passed to the <i>Krb5LoginModule</i>.
* These options instruct the <i>Krb5LoginModule</i> to
* use the ticket cache at the specified location.
* The system properties, <i>user.home</i> and <i>/</i>
* (file.separator), are expanded to their respective values.
*
* <p> There is only one Configuration object installed in the runtime at any
* given time.  A Configuration object can be installed by calling the
* {@code setConfiguration} method.  The installed Configuration object
* can be obtained by calling the {@code getConfiguration} method.
*
* <p> If no Configuration object has been installed in the runtime, a call to
* {@code getConfiguration} installs an instance of the default
* Configuration implementation (a default subclass implementation of this
* abstract class).
* The default Configuration implementation can be changed by setting the value
* of the {@code login.configuration.provider} security property to the fully
* qualified name of the desired Configuration subclass implementation.
*
* <p> Application code can directly subclass Configuration to provide a custom
* implementation.  In addition, an instance of a Configuration object can be
* constructed by invoking one of the {@code getInstance} factory methods
* with a standard type.  The default policy type is "JavaLoginConfig".
* See the Configuration section in the <a href=
* "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
* Java Cryptography Architecture Standard Algorithm Name Documentation</a>
* for a list of standard Configuration types.
*
* @see javax.security.auth.login.LoginContext
* @see java.security.Security security properties
*/
public abstract class Configuration {

    private static Configuration configuration;

    private final java.security.AccessControlContext acc =
            java.security.AccessController.getContext();

    private static void checkPermission(String type) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new AuthPermission
                                ("createLoginConfiguration." + type));
        }
    }

    /**
     * Sole constructor.  (For invocation by subclass constructors, typically
     * implicit.)
     */
    protected Configuration() { }

    /**
     * Get the installed login Configuration.
     *
     * <p>
     *
     * @return the login Configuration.  If a Configuration object was set
     *          via the {@code Configuration.setConfiguration} method,
     *          then that object is returned.  Otherwise, a default
     *          Configuration object is returned.
     *
     * @exception SecurityException if the caller does not have permission
     *                          to retrieve the Configuration.
     *
     * @see #setConfiguration
     */
    public static Configuration getConfiguration() {

        SecurityManager sm = System.getSecurityManager();
        if (sm != null)
            sm.checkPermission(new AuthPermission("getLoginConfiguration"));

        synchronized (Configuration.class) {
            if (configuration == null) {
                String config_class = null;
                config_class = AccessController.doPrivileged
                    (new PrivilegedAction<String>() {
                    public String run() {
                        return java.security.Security.getProperty
                                    ("login.configuration.provider");
                    }
                });
                if (config_class == null) {
                    config_class = "sun.security.provider.ConfigFile";
                }

                try {
                    final String finalClass = config_class;
                    Configuration untrustedImpl = AccessController.doPrivileged(
                            new PrivilegedExceptionAction<Configuration>() {
                                public Configuration run() throws ClassNotFoundException,
                                        InstantiationException,
                                        IllegalAccessException {
                                    Class<? extends Configuration> implClass = Class.forName(
                                            finalClass, false,
                                            Thread.currentThread().getContextClassLoader()
                                    ).asSubclass(Configuration.class);
                                    return implClass.newInstance();
                                }
                            });
                    AccessController.doPrivileged(
                            new PrivilegedExceptionAction<Void>() {
                                public Void run() {
                                    setConfiguration(untrustedImpl);
                                    return null;
                                }
                            }, Objects.requireNonNull(untrustedImpl.acc)
                    );
                } catch (PrivilegedActionException e) {
                    Exception ee = e.getException();
                    if (ee instanceof InstantiationException) {
                        throw (SecurityException) new
                            SecurityException
                                    ("Configuration error:" +
                                     ee.getCause().getMessage() +
                                     "\n").initCause(ee.getCause());
                    } else {
                        throw (SecurityException) new
                            SecurityException
                                    ("Configuration error: " +
                                     ee.toString() +
                                     "\n").initCause(ee);
                    }
                }
            }
            return configuration;
        }
    }

    /**
     * Set the login {@code Configuration}.
     *
     * <p>
     *
     * @param configuration the new {@code Configuration}
     *
     * @exception SecurityException if the current thread does not have
     *                  Permission to set the {@code Configuration}.
     *
     * @see #getConfiguration
     */
    public static void setConfiguration(Configuration configuration) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null)
            sm.checkPermission(new AuthPermission("setLoginConfiguration"));
        Configuration.configuration = configuration;
    }

    /**
     * Returns a Configuration object of the specified type.
     *
     * <p> This method traverses the list of registered security providers,
     * starting with the most preferred Provider.
     * A new Configuration object encapsulating the
     * ConfigurationSpi implementation from the first
     * Provider that supports the specified type is returned.
     *
     * <p> Note that the list of registered providers may be retrieved via
     * the {@link Security#getProviders() Security.getProviders()} method.
     *
     * @param type the specified Configuration type.  See the Configuration
     *    section in the <a href=
     *    "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
     *    Java Cryptography Architecture Standard Algorithm Name
     *    Documentation</a> for a list of standard Configuration types.
     *
     * @param params parameters for the Configuration, which may be null.
     *
     * @return the new Configuration object.
     *
     * @exception SecurityException if the caller does not have permission
     *          to get a Configuration instance for the specified type.
     *
     * @exception NullPointerException if the specified type is null.
     *
     * @exception IllegalArgumentException if the specified parameters
     *          are not understood by the ConfigurationSpi implementation
     *          from the selected Provider.
     *
     * @exception NoSuchAlgorithmException if no Provider supports a
     *          ConfigurationSpi implementation for the specified type.
     *
     * @see Provider
     * @since 1.6
     */
    public static Configuration getInstance(String type,
                                Configuration.Parameters params)
                throws NoSuchAlgorithmException {

        checkPermission(type);
        try {
            GetInstance.Instance instance = GetInstance.getInstance
                                                        ("Configuration",
                                                        ConfigurationSpi.class,
                                                        type,
                                                        params);
            return new ConfigDelegate((ConfigurationSpi)instance.impl,
                                                        instance.provider,
                                                        type,
                                                        params);
        } catch (NoSuchAlgorithmException nsae) {
            return handleException (nsae);
        }
    }

    /**
     * Returns a Configuration object of the specified type.
     *
     * <p> A new Configuration object encapsulating the
     * ConfigurationSpi implementation from the specified provider
     * is returned.   The specified provider must be registered
     * in the provider list.
     *
     * <p> Note that the list of registered providers may be retrieved via
     * the {@link Security#getProviders() Security.getProviders()} method.
     *
     * @param type the specified Configuration type.  See the Configuration
     *    section in the <a href=
     *    "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
     *    Java Cryptography Architecture Standard Algorithm Name
     *    Documentation</a> for a list of standard Configuration types.
     *
     * @param params parameters for the Configuration, which may be null.
     *
     * @param provider the provider.
     *
     * @return the new Configuration object.
     *
     * @exception SecurityException if the caller does not have permission
     *          to get a Configuration instance for the specified type.
     *
     * @exception NullPointerException if the specified type is null.
     *
     * @exception IllegalArgumentException if the specified provider
     *          is null or empty,
     *          or if the specified parameters are not understood by
     *          the ConfigurationSpi implementation from the specified provider.
     *
     * @exception NoSuchProviderException if the specified provider is not
     *          registered in the security provider list.
     *
     * @exception NoSuchAlgorithmException if the specified provider does not
     *          support a ConfigurationSpi implementation for the specified
     *          type.
     *
     * @see Provider
     * @since 1.6
     */
    public static Configuration getInstance(String type,
                                Configuration.Parameters params,
                                String provider)
                throws NoSuchProviderException, NoSuchAlgorithmException {

        if (provider == null || provider.length() == 0) {
            throw new IllegalArgumentException("missing provider");
        }

        checkPermission(type);
        try {
            GetInstance.Instance instance = GetInstance.getInstance
                                                        ("Configuration",
                                                        ConfigurationSpi.class,
                                                        type,
                                                        params,
                                                        provider);
            return new ConfigDelegate((ConfigurationSpi)instance.impl,
                                                        instance.provider,
                                                        type,
                                                        params);
        } catch (NoSuchAlgorithmException nsae) {
            return handleException (nsae);
        }
    }

    /**
     * Returns a Configuration object of the specified type.
     *
     * <p> A new Configuration object encapsulating the
     * ConfigurationSpi implementation from the specified Provider
     * object is returned.  Note that the specified Provider object
     * does not have to be registered in the provider list.
     *
     * @param type the specified Configuration type.  See the Configuration
     *    section in the <a href=
     *    "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
     *    Java Cryptography Architecture Standard Algorithm Name
     *    Documentation</a> for a list of standard Configuration types.
     *
     * @param params parameters for the Configuration, which may be null.
     *
     * @param provider the Provider.
     *
     * @return the new Configuration object.
     *
     * @exception SecurityException if the caller does not have permission
     *          to get a Configuration instance for the specified type.
     *
     * @exception NullPointerException if the specified type is null.
     *
     * @exception IllegalArgumentException if the specified Provider is null,
     *          or if the specified parameters are not understood by
     *          the ConfigurationSpi implementation from the specified Provider.
     *
     * @exception NoSuchAlgorithmException if the specified Provider does not
     *          support a ConfigurationSpi implementation for the specified
     *          type.
     *
     * @see Provider
     * @since 1.6
     */
    public static Configuration getInstance(String type,
                                Configuration.Parameters params,
                                Provider provider)
                throws NoSuchAlgorithmException {

        if (provider == null) {
            throw new IllegalArgumentException("missing provider");
        }

        checkPermission(type);
        try {
            GetInstance.Instance instance = GetInstance.getInstance
                                                        ("Configuration",
                                                        ConfigurationSpi.class,
                                                        type,
                                                        params,
                                                        provider);
            return new ConfigDelegate((ConfigurationSpi)instance.impl,
                                                        instance.provider,
                                                        type,
                                                        params);
        } catch (NoSuchAlgorithmException nsae) {
            return handleException (nsae);
        }
    }

    private static Configuration handleException(NoSuchAlgorithmException nsae)
                throws NoSuchAlgorithmException {
        Throwable cause = nsae.getCause();
        if (cause instanceof IllegalArgumentException) {
            throw (IllegalArgumentException)cause;
        }
        throw nsae;
    }

    /**
     * Return the Provider of this Configuration.
     *
     * <p> This Configuration instance will only have a Provider if it
     * was obtained via a call to {@code Configuration.getInstance}.
     * Otherwise this method returns null.
     *
     * @return the Provider of this Configuration, or null.
     *
     * @since 1.6
     */
    public Provider getProvider() {
        return null;
    }

    /**
     * Return the type of this Configuration.
     *
     * <p> This Configuration instance will only have a type if it
     * was obtained via a call to {@code Configuration.getInstance}.
     * Otherwise this method returns null.
     *
     * @return the type of this Configuration, or null.
     *
     * @since 1.6
     */
    public String getType() {
        return null;
    }

    /**
     * Return Configuration parameters.
     *
     * <p> This Configuration instance will only have parameters if it
     * was obtained via a call to {@code Configuration.getInstance}.
     * Otherwise this method returns null.
     *
     * @return Configuration parameters, or null.
     *
     * @since 1.6
     */
    public Configuration.Parameters getParameters() {
        return null;
    }

    /**
     * Retrieve the AppConfigurationEntries for the specified <i>name</i>
     * from this Configuration.
     *
     * <p>
     *
     * @param name the name used to index the Configuration.
     *
     * @return an array of AppConfigurationEntries for the specified <i>name</i>
     *          from this Configuration, or null if there are no entries
     *          for the specified <i>name</i>
     */
    public abstract AppConfigurationEntry[] getAppConfigurationEntry
                                                        (String name);

    /**
     * Refresh and reload the Configuration.
     *
     * <p> This method causes this Configuration object to refresh/reload its
     * contents in an implementation-dependent manner.
     * For example, if this Configuration object stores its entries in a file,
     * calling {@code refresh} may cause the file to be re-read.
     *
     * <p> The default implementation of this method does nothing.
     * This method should be overridden if a refresh operation is supported
     * by the implementation.
     *
     * @exception SecurityException if the caller does not have permission
     *                          to refresh its Configuration.
     */
    public void refresh() { }

    /**
     * This subclass is returned by the getInstance calls.  All Configuration
     * calls are delegated to the underlying ConfigurationSpi.
     */
    private static class ConfigDelegate extends Configuration {

        private ConfigurationSpi spi;
        private Provider p;
        private String type;
        private Configuration.Parameters params;

        private ConfigDelegate(ConfigurationSpi spi, Provider p,
                        String type, Configuration.Parameters params) {
            this.spi = spi;
            this.p = p;
            this.type = type;
            this.params = params;
        }

        public String getType() { return type; }

        public Configuration.Parameters getParameters() { return params; }

        public Provider getProvider() { return p; }

        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
            return spi.engineGetAppConfigurationEntry(name);
        }

        public void refresh() {
            spi.engineRefresh();
        }
    }

    /**
     * This represents a marker interface for Configuration parameters.
     *
     * @since 1.6
     */
    public static interface Parameters { }
}
TOP

Related Classes of javax.security.auth.login.Configuration$Parameters

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.