logincontext.java
来自「java jdk 1.4的源码」· Java 代码 · 共 840 行 · 第 1/3 页
JAVA
840 行
/* * @(#)LoginContext.java 1.94 03/01/23 * * Copyright 2003 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.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. * Therefore, 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. In other words, * an application may be configured to use more than one * <code>LoginModule</code>. For example, one could * configure both a Kerberos <code>LoginModule</code> and a smart card * <code>LoginModule</code> under an application. * * <p> A typical caller instantiates this class and passes in * a <i>name</i> and a <code>CallbackHandler</code>. * <code>LoginContext</code> uses the <i>name</i> as the index into the * <code>Configuration</code> 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 <code>LoginContext</code>, * it invokes the <code>login</code> method to authenticate * a <code>Subject</code>. This <code>login</code> method invokes the * <code>login</code> method from each of the LoginModules configured for * the <i>name</i> specified by the caller. Each <code>LoginModule</code> * then performs its respective type of authentication (username/password, * smart card pin verification, etc.). Note that the LoginModules will not * attempt authentication retries or introduce delays if the authentication * fails. Such tasks belong to the caller. * * <p> Regardless of whether or not the overall authentication succeeded, * this <code>login</code> method completes a 2-phase authentication process * by then calling either the <code>commit</code> method or the * <code>abort</code> method for each of the configured LoginModules. * The <code>commit</code> method for each <code>LoginModule</code> * gets invoked if the overall authentication succeeded, * whereas the <code>abort</code> method for each <code>LoginModule</code> * gets invoked if the overall authentication failed. * Each successful LoginModule's <code>commit</code> * method associates the relevant Principals (authenticated identities) * and Credentials (authentication data such as cryptographic keys) * with the <code>Subject</code>. Each LoginModule's <code>abort</code> * method cleans up or removes/destroys any previously stored authentication * state. * * <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 <code>Subject</code> by invoking the * <code>getSubject</code> method. Principals and Credentials associated * with the <code>Subject</code> may be retrieved by invoking the Subject's * respective <code>getPrincipals</code>, <code>getPublicCredentials</code>, * and <code>getPrivateCredentials</code> methods. * * <p> To logout the <code>Subject</code>, the caller simply needs to * invoke the <code>logout</code> method. As with the <code>login</code> * method, this <code>logout</code> method invokes the <code>logout</code> * method for each <code>LoginModule</code> configured for this * <code>LoginContext</code>. Each LoginModule's <code>logout</code> * method cleans up state and removes/destroys Principals and Credentials * from the <code>Subject</code> as appropriate. * * <p> Each of the configured LoginModules invoked by the * <code>LoginContext</code> is initialized with a * <code>Subject</code> to be authenticated, a <code>CallbackHandler</code> * used to communicate with users, shared <code>LoginModule</code> state, * and LoginModule-specific options. If the <code>LoginContext</code> * was not provided a <code>Subject</code> then it instantiates one itself. * * <p> Each <code>LoginModule</code> * which successfully authenticates a user updates the <code>Subject</code> * with the relevant user information (Principals and Credentials). * This <code>Subject</code> can then be returned via the * <code>getSubject</code> method from the <code>LoginContext</code> class * if the overall authentication succeeds. Note that LoginModules are always * invoked from within an <code>AccessController.doPrivileged</code> call. * Therefore, although LoginModules that perform security-sensitive tasks * (such as connecting to remote hosts) need to be granted the relevant * Permissions in the security <code>Policy</code>, the callers of the * LoginModules do not require those Permissions. * * <p> A <code>LoginContext</code> supports authentication retries * by the calling application. For example, a LoginContext's * <code>login</code> method may be invoked multiple times * if the user incorrectly types in a password. However, a * <code>LoginContext</code> should not be used to authenticate * more than one <code>Subject</code>. A separate <code>LoginContext</code> * should be used to authenticate each different <code>Subject</code>. * * <p> Multiple calls into the same <code>LoginContext</code> * do not affect the <code>LoginModule</code> state, or the * LoginModule-specific options. * * @version 1.94, 01/23/03 * @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 ModuleInfo[] moduleStack; private ClassLoader contextClassLoader = null; private static final Class[] PARAMS = { }; private static final sun.security.util.Debug debug = sun.security.util.Debug.getInstance("logincontext", "\t[LoginContext]"); private void init(String name) throws LoginException { java.lang.SecurityManager sm = System.getSecurityManager(); if (sm != null) { 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) { 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 ("auth.login.defaultCallbackHandler"); 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) { this.callbackHandler = new SecureCallbackHandler (java.security.AccessController.getContext(), this.callbackHandler); } } /** * Constructor for the <code>LoginContext</code> class. * * <p> Initialize the new <code>LoginContext</code> object with a name. * <code>LoginContext</code> uses the specified name as the index * into the <code>Configuration</code> to determine which LoginModules * should be used. If the provided name does not match any in the * <code>Configuration</code>, then the <code>LoginContext</code> * uses the default <code>Configuration</code> entry, "<i>other</i>". * If there is no <code>Configuration</code> entry for "<i>other</i>", * then a <code>LoginException</code> is thrown. * * <p> This constructor does not allow for a <code>CallbackHandler</code>. * If the <i>auth.login.defaultCallbackHandler</i> security property * is set to the fully qualified name of a default * <code>CallbackHandler</code> implementation class, * then that <code>CallbackHandler</code> will be loaded and * passed to the underlying LoginModules. If the security property * is not set, then the underlying LoginModules * will not have a <code>CallbackHandler</code> for use in communicating * with users. The caller thus assumes that the configured * LoginModules have alternative means for authenticating the user. * * <p> The <i>auth.login.defaultCallbackHandler</i> security property * can be set in the Java security properties file located in the * file named <JAVA_HOME>/lib/security/java.security, * where <JAVA_HOME> refers to the directory where the SDK * was installed. * * <p> Since no <code>Subject</code> can be specified to this constructor, * it instantiates a <code>Subject</code> itself. * * <p> * * @param name the name used as the index into the
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?