📄 logincontext.java
字号:
/* * @(#)LoginContext.java 1.100 05/11/17 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package javax.security.auth.login;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import java.lang.reflect.InvocationTargetException;import java.util.LinkedList;import java.util.Map;import java.util.HashMap;import java.text.MessageFormat;import javax.security.auth.Subject;import javax.security.auth.AuthPermission;import javax.security.auth.callback.*;import java.security.AccessController;import java.security.AccessControlContext;import sun.security.util.PendingException;import sun.security.util.ResourcesMgr;/** * <p> The <code>LoginContext</code> class describes the basic methods used * to authenticate Subjects and provides a way to develop an * application independent of the underlying authentication technology. * A <code>Configuration</code> specifies the authentication technology, or * <code>LoginModule</code>, to be used with a particular application. * Different LoginModules can be plugged in under an application * without requiring any modifications to the application itself. * * <p> In addition to supporting <i>pluggable</i> authentication, this class * also supports the notion of <i>stacked</i> authentication. * Applications may be configured to use more than one * LoginModule. For example, one could * configure both a Kerberos LoginModule and a smart card * LoginModule under an application. * * <p> A typical caller instantiates a LoginContext with * a <i>name</i> and a <code>CallbackHandler</code>. * LoginContext uses the <i>name</i> as the index into a * Configuration to determine which LoginModules should be used, * and which ones must succeed in order for the overall authentication to * succeed. The <code>CallbackHandler</code> is passed to the underlying * LoginModules so they may communicate and interact with users * (prompting for a username and password via a graphical user interface, * for example). * * <p> Once the caller has instantiated a LoginContext, * it invokes the <code>login</code> method to authenticate * a <code>Subject</code>. The <code>login</code> method invokes * the configured modules to perform their respective types of authentication * (username/password, smart card pin verification, etc.). * Note that the LoginModules will not attempt authentication retries nor * introduce delays if the authentication fails. * Such tasks belong to the LoginContext caller. * * <p> If the <code>login</code> method returns without * throwing an exception, then the overall authentication succeeded. * The caller can then retrieve * the newly authenticated Subject by invoking the * <code>getSubject</code> method. Principals and Credentials associated * with the Subject may be retrieved by invoking the Subject's * respective <code>getPrincipals</code>, <code>getPublicCredentials</code>, * and <code>getPrivateCredentials</code> methods. * * <p> To logout the Subject, the caller calls * the <code>logout</code> method. As with the <code>login</code> * method, this <code>logout</code> method invokes the <code>logout</code> * method for the configured modules. * * <p> A LoginContext should not be used to authenticate * more than one Subject. A separate LoginContext * should be used to authenticate each different Subject. * * <p> The following documentation applies to all LoginContext constructors: * <ol> * * <li> <code>Subject</code> * <ul> * <li> If the constructor has a Subject * input parameter, the LoginContext uses the caller-specified * Subject object. * <p> * <li> If the caller specifies a <code>null</code> Subject * and a <code>null</code> value is permitted, * the LoginContext instantiates a new Subject. * <p> * <li> If the constructor does <b>not</b> have a Subject * input parameter, the LoginContext instantiates a new Subject. * <p> * </ul> * * <li> <code>Configuration</code> * <ul> * <li> If the constructor has a Configuration * input parameter and the caller specifies a non-null Configuration, * the LoginContext uses the caller-specified Configuration. * <p> * If the constructor does <b>not</b> have a Configuration * input parameter, or if the caller specifies a <code>null</code> * Configuration object, the constructor uses the following call to * get the installed Configuration: * <pre> * config = Configuration.getConfiguration(); * </pre> * For both cases, * the <i>name</i> argument given to the constructor is passed to the * <code>Configuration.getAppConfigurationEntry</code> method. * If the Configuration has no entries for the specified <i>name</i>, * then the <code>LoginContext</code> calls * <code>getAppConfigurationEntry</code> with the name, "<i>other</i>" * (the default entry name). If there is no entry for "<i>other</i>", * then a <code>LoginException</code> is thrown. * <p> * <li> When LoginContext uses the installed Configuration, the caller * requires the createLoginContext.<em>name</em> and possibly * createLoginContext.other AuthPermissions. Furthermore, the * LoginContext will invoke configured modules from within an * <code>AccessController.doPrivileged</code> call so that modules that * perform security-sensitive tasks (such as connecting to remote hosts, * and updating the Subject) will require the respective permissions, but * the callers of the LoginContext will not require those permissions. * <p> * <li> When LoginContext uses a caller-specified Configuration, the caller * does not require any createLoginContext AuthPermission. The LoginContext * saves the <code>AccessControlContext</code> for the caller, * and invokes the configured modules from within an * <tt>AccessController.doPrivileged</tt> call constrained by that context. * This means the caller context (stored when the LoginContext was created) * must have sufficient permissions to perform any security-sensitive tasks * that the modules may perform. * <p> * </ul> * * <li> <code>CallbackHandler</code> * <ul> * <li> If the constructor has a CallbackHandler * input parameter, the LoginContext uses the caller-specified * CallbackHandler object. * <p> * <li> If the constructor does <b>not</b> have a CallbackHandler * input parameter, or if the caller specifies a <code>null</code> * CallbackHandler object (and a <code>null</code> value is permitted), * the LoginContext queries the * <i>auth.login.defaultCallbackHandler</i> security property * for the fully qualified class name of a default handler implementation. * If the security property is not set, * then the underlying modules will not have a * CallbackHandler for use in communicating * with users. The caller thus assumes that the configured * modules have alternative means for authenticating the user. * * <p> * <li> When the LoginContext uses the installed Configuration (instead of * a caller-specified Configuration, see above), * then this LoginContext must wrap any * caller-specified or default CallbackHandler implementation * in a new CallbackHandler implementation * whose <code>handle</code> method implementation invokes the * specified CallbackHandler's <code>handle</code> method in a * <code>java.security.AccessController.doPrivileged</code> call * constrained by the caller's current <code>AccessControlContext</code>. * </ul> * </ol> * * <p> Note that Security Properties * (such as <code>auth.login.defaultCallbackHandler</code>) * can be set programmatically via the * <code>java.security.Security</code> class, * or statically in the Java security properties file located in the * file named <JAVA_HOME>/lib/security/java.security. * <JAVA_HOME> refers to the value of the java.home system property, * and specifies the directory where the JRE is installed. * * @version 1.100, 11/17/05 * @see java.security.Security * @see javax.security.auth.AuthPermission * @see javax.security.auth.Subject * @see javax.security.auth.callback.CallbackHandler * @see javax.security.auth.login.Configuration * @see javax.security.auth.spi.LoginModule */public class LoginContext { private static final String INIT_METHOD = "initialize"; private static final String LOGIN_METHOD = "login"; private static final String COMMIT_METHOD = "commit"; private static final String ABORT_METHOD = "abort"; private static final String LOGOUT_METHOD = "logout"; private static final String OTHER = "other"; private static final String DEFAULT_HANDLER = "auth.login.defaultCallbackHandler"; private Subject subject = null; private boolean subjectProvided = false; private boolean loginSucceeded = false; private CallbackHandler callbackHandler; private Map state = new HashMap(); private Configuration config; private boolean configProvided = false; private AccessControlContext creatorAcc = null; private ModuleInfo[] moduleStack; private ClassLoader contextClassLoader = null; private static final Class[] PARAMS = { }; // state saved in the event a user-specified asynchronous exception // was specified and thrown private int moduleIndex = 0; private LoginException firstError = null; private LoginException firstRequiredError = null; private boolean success = false; private static final sun.security.util.Debug debug = sun.security.util.Debug.getInstance("logincontext", "\t[LoginContext]"); private void init(String name) throws LoginException { SecurityManager sm = System.getSecurityManager(); if (sm != null && !configProvided) { sm.checkPermission(new AuthPermission ("createLoginContext." + name)); } if (name == null) throw new LoginException (ResourcesMgr.getString("Invalid null input: name")); // get the Configuration if (config == null) { config = (Configuration)java.security.AccessController.doPrivileged (new java.security.PrivilegedAction() { public Object run() { return Configuration.getConfiguration(); } }); } // get the LoginModules configured for this application AppConfigurationEntry[] entries = config.getAppConfigurationEntry(name); if (entries == null) { if (sm != null && !configProvided) { sm.checkPermission(new AuthPermission ("createLoginContext." + OTHER)); } entries = config.getAppConfigurationEntry(OTHER); if (entries == null) { MessageFormat form = new MessageFormat(ResourcesMgr.getString ("No LoginModules configured for name")); Object[] source = {name}; throw new LoginException(form.format(source)); } } moduleStack = new ModuleInfo[entries.length]; for (int i = 0; i < entries.length; i++) { // clone returned array moduleStack[i] = new ModuleInfo (new AppConfigurationEntry (entries[i].getLoginModuleName(), entries[i].getControlFlag(), entries[i].getOptions()), null); } contextClassLoader = (ClassLoader)java.security.AccessController.doPrivileged (new java.security.PrivilegedAction() { public Object run() { return Thread.currentThread().getContextClassLoader(); } }); } private void loadDefaultCallbackHandler() throws LoginException { // get the default handler class try { final ClassLoader finalLoader = contextClassLoader; this.callbackHandler = (CallbackHandler) java.security.AccessController.doPrivileged (new java.security.PrivilegedExceptionAction() { public Object run() throws Exception { String defaultHandler = java.security.Security.getProperty (DEFAULT_HANDLER); if (defaultHandler == null || defaultHandler.length() == 0) return null; Class c = Class.forName(defaultHandler, true, finalLoader); return c.newInstance(); } }); } catch (java.security.PrivilegedActionException pae) { throw new LoginException(pae.getException().toString()); } // secure it with the caller's ACC if (this.callbackHandler != null && !configProvided) { this.callbackHandler = new SecureCallbackHandler (java.security.AccessController.getContext(), this.callbackHandler); } } /** * Instantiate a new <code>LoginContext</code> object with a name. * * @param name the name used as the index into the * <code>Configuration</code>. * * @exception LoginException if the caller-specified <code>name</code> * does not appear in the <code>Configuration</code> * and there is no <code>Configuration</code> entry * for "<i>other</i>", or if the * <i>auth.login.defaultCallbackHandler</i> * security property was set, but the implementation * class could not be loaded. * <p> * @exception SecurityException if a SecurityManager is set and * the caller does not have * AuthPermission("createLoginContext.<i>name</i>"),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -