/* * @(#)Configuration.java 1.57 03/12/19 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package javax.security.auth.login; import javax.security.auth.AuthPermission; import java.io.*; import java.util.*; import java.net.URL; import java.security.PrivilegedActionException; /** *
This is an abstract class for representing the configuration of
* LoginModules under an application. The Configuration
specifies
* which LoginModules should be used for a particular application, and in what
* order the LoginModules should be invoked.
* This abstract class needs to be subclassed to provide an implementation
* which reads and loads the actual Configuration
.
*
*
A login configuration contains the following information.
* Note that this example only represents the default syntax for the
* Configuration
. Subclass implementations of this class
* may implement alternative syntaxes and may retrieve the
* Configuration
from any source such as files, databases,
* or servers.
*
*
* Name { * ModuleClass Flag ModuleOptions; * ModuleClass Flag ModuleOptions; * ModuleClass Flag ModuleOptions; * }; * Name { * ModuleClass Flag ModuleOptions; * ModuleClass Flag ModuleOptions; * }; * other { * ModuleClass Flag ModuleOptions; * ModuleClass Flag ModuleOptions; * }; ** *
Each entry in the Configuration
is indexed via an
* application name, Name, and contains a list of
* LoginModules configured for that application. Each 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 specific entry,
* it defaults to the specific entry for "other".
*
*
The Flag value controls the overall behavior as authentication * proceeds down the stack. The following represents a description of the * valid values for Flag and their respective semantics: * *
* 1) Required - The* *LoginModule
is required to succeed. * If it succeeds or fails, authentication still continues * to proceed down theLoginModule
list. * * 2) Requisite - TheLoginModule
is required to succeed. * If it succeeds, authentication continues down the *LoginModule
list. If it fails, * control immediately returns to the application * (authentication does not proceed down the *LoginModule
list). * * 3) Sufficient - TheLoginModule
is not required to * succeed. If it does succeed, control immediately * returns to the application (authentication does not * proceed down theLoginModule
list). * If it fails, authentication continues down the *LoginModule
list. * * 4) Optional - TheLoginModule
is not required to * succeed. If it succeeds or fails, * authentication still continues to proceed down the *LoginModule
list. *
The overall authentication succeeds only if all Required and
* Requisite LoginModules succeed. If a Sufficient
* LoginModule
is configured and succeeds,
* then only the Required and Requisite LoginModules prior to
* that Sufficient LoginModule
need to have succeeded for
* the overall authentication to succeed. If no Required or
* Requisite LoginModules are configured for an application,
* then at least one Sufficient or Optional
* LoginModule
must succeed.
*
*
ModuleOptions is a space separated list of
* LoginModule
-specific values which are passed directly to
* the underlying LoginModules. Options are defined by the
* LoginModule
itself, and control the behavior within it.
* For example, a LoginModule
may define options to support
* debugging/testing capabilities. The correct way to specify options in the
* Configuration
is by using the following key-value pairing:
* debug="true". 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 LoginModule
may define.
*
*
The following represents an example Configuration
entry
* based on the syntax above:
*
*
* Login { * com.sun.security.auth.module.UnixLoginModule required; * com.sun.security.auth.module.Krb5LoginModule optional * useTicketCache="true" * ticketCache="${user.home}${/}tickets"; * }; ** *
This Configuration
specifies that an application named,
* "Login", requires users to first authenticate to the
* com.sun.security.auth.module.UnixLoginModule, which is
* required to succeed. Even if the UnixLoginModule
* authentication fails, the
* com.sun.security.auth.module.Krb5LoginModule
* still gets invoked. This helps hide the source of failure.
* Since the Krb5LoginModule is Optional, the overall
* authentication succeeds only if the UnixLoginModule
* (Required) succeeds.
*
*
Also note that the LoginModule-specific options, * useTicketCache="true" and * ticketCache=${user.home}${/}tickets", * are passed to the Krb5LoginModule. * These options instruct the Krb5LoginModule to * use the ticket cache at the specified location. * The system properties, user.home and / * (file.separator), are expanded to their respective values. * *
The default Configuration implementation can be changed by setting the * value of the "login.configuration.provider" security property (in the Java * security properties file) to the fully qualified name of * the desired Configuration implementation class. * The Java security properties file is located in the file named * <JAVA_HOME>/lib/security/java.security, where <JAVA_HOME> * refers to the directory where the JDK was installed. * * @version 1.57, 12/19/03 * @see javax.security.auth.login.LoginContext */ public abstract class Configuration { private static Configuration configuration; private static ClassLoader contextClassLoader; static { contextClassLoader = (ClassLoader)java.security.AccessController.doPrivileged (new java.security.PrivilegedAction() { public Object run() { return Thread.currentThread().getContextClassLoader(); } }); }; /** * Sole constructor. (For invocation by subclass constructors, typically * implicit.) */ protected Configuration() { } /** * Get the Login Configuration. * *
*
* @return the login Configuration. If a Configuration object was set
* via the 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 synchronized Configuration getConfiguration() {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new AuthPermission("getLoginConfiguration"));
if (configuration == null) {
String config_class = null;
config_class = (String)
java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction() {
public Object run() {
return java.security.Security.getProperty
("login.configuration.provider");
}
});
if (config_class == null) {
config_class = "com.sun.security.auth.login.ConfigFile";
}
try {
final String finalClass = config_class;
configuration = (Configuration)
java.security.AccessController.doPrivileged
(new java.security.PrivilegedExceptionAction() {
public Object run() throws ClassNotFoundException,
InstantiationException,
IllegalAccessException {
return Class.forName
(finalClass,
true,
contextClassLoader).newInstance();
}
});
} 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 Configuration
.
*
*
*
* @param configuration the new Configuration
*
* @exception SecurityException if the current thread does not have
* Permission to set the Configuration
.
*
* @see #getConfiguration
*/
public static void setConfiguration(Configuration configuration) {
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new AuthPermission("setLoginConfiguration"));
Configuration.configuration = configuration;
}
/**
* Retrieve the AppConfigurationEntries for the specified name
* from this Configuration.
*
*
* * @param name the name used to index the Configuration. * * @return an array of AppConfigurationEntries for the specified name * from this Configuration, or null if there are no entries * for the specified name */ public abstract AppConfigurationEntry[] getAppConfigurationEntry (String name); /** * Refresh and reload the Configuration. * *
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 refresh
may cause the file to be re-read.
*
*
* * @exception SecurityException if the caller does not have permission * to refresh its Configuration. */ public abstract void refresh(); }