📄 fileloginmodule.java
字号:
/* * @(#)FileLoginModule.java 1.5 06/09/29 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.jmx.remote.security;import java.io.BufferedInputStream;import java.io.File;import java.io.FileInputStream;import java.io.FilePermission;import java.io.IOException;import java.security.AccessControlException;import java.security.AccessController;import java.util.Arrays;import java.util.Hashtable;import java.util.Map;import java.util.Properties;import javax.security.auth.*;import javax.security.auth.callback.*;import javax.security.auth.login.*;import javax.security.auth.spi.*;import javax.management.remote.JMXPrincipal;import com.sun.jmx.remote.util.ClassLogger;import com.sun.jmx.remote.util.EnvHelp;import sun.management.jmxremote.ConnectorBootstrap;import sun.security.action.GetPropertyAction;/** * This {@link LoginModule} performs file-based authentication. * * <p> A supplied username and password is verified against the * corresponding user credentials stored in a designated password file. * If successful then a new {@link JMXPrincipal} is created with the * user's name and it is associated with the current {@link Subject}. * Such principals may be identified and granted management privileges in * the access control file for JMX remote management or in a Java security * policy. * * <p> The password file comprises a list of key-value pairs as specified in * {@link Properties}. The key represents a user's name and the value is its * associated cleartext password. By default, the following password file is * used: * <pre> * ${java.home}/lib/management/jmxremote.password * </pre> * A different password file can be specified via the <code>passwordFile</code> * configuration option. * * <p> This module recognizes the following <code>Configuration</code> options: * <dl> * <dt> <code>passwordFile</code> </dt> * <dd> the path to an alternative password file. It is used instead of * the default password file.</dd> * * <dt> <code>useFirstPass</code> </dt> * <dd> if <code>true</code>, this module retrieves the username and password * from the module's shared state, using "javax.security.auth.login.name" * and "javax.security.auth.login.password" as the respective keys. The * retrieved values are used for authentication. If authentication fails, * no attempt for a retry is made, and the failure is reported back to * the calling application.</dd> * * <dt> <code>tryFirstPass</code> </dt> * <dd> if <code>true</code>, this module retrieves the username and password * from the module's shared state, using "javax.security.auth.login.name" * and "javax.security.auth.login.password" as the respective keys. The * retrieved values are used for authentication. If authentication fails, * the module uses the CallbackHandler to retrieve a new username and * password, and another attempt to authenticate is made. If the * authentication fails, the failure is reported back to the calling * application.</dd> * * <dt> <code>storePass</code> </dt> * <dd> if <code>true</code>, this module stores the username and password * obtained from the CallbackHandler in the module's shared state, using * "javax.security.auth.login.name" and * "javax.security.auth.login.password" as the respective keys. This is * not performed if existing values already exist for the username and * password in the shared state, or if authentication fails.</dd> * * <dt> <code>clearPass</code> </dt> * <dd> if <code>true</code>, this module clears the username and password * stored in the module's shared state after both phases of authentication * (login and commit) have completed.</dd> * </dl> */public class FileLoginModule implements LoginModule { // Location of the default password file private static final String DEFAULT_PASSWORD_FILE_NAME = ((String) AccessController.doPrivileged( new GetPropertyAction("java.home"))) + File.separatorChar + "lib" + File.separatorChar + "management" + File.separatorChar + ConnectorBootstrap.DefaultValues.PASSWORD_FILE_NAME; // Key to retrieve the stored username private static final String USERNAME_KEY = "javax.security.auth.login.name"; // Key to retrieve the stored password private static final String PASSWORD_KEY = "javax.security.auth.login.password"; // Log messages private static final ClassLogger logger = new ClassLogger("javax.management.remote.misc", "FileLoginModule"); // Configurable options private boolean useFirstPass = false; private boolean tryFirstPass = false; private boolean storePass = false; private boolean clearPass = false; // Authentication status private boolean succeeded = false; private boolean commitSucceeded = false; // Supplied username and password private String username; private char[] password; private JMXPrincipal user; // Initial state private Subject subject; private CallbackHandler callbackHandler; private Map sharedState; private Map options; private String passwordFile; private String passwordFileDisplayName; private boolean userSuppliedPasswordFile; private boolean hasJavaHomePermission; private Properties userCredentials; /** * Initialize this <code>LoginModule</code>. * * @param subject the <code>Subject</code> to be authenticated. * @param callbackHandler a <code>CallbackHandler</code> to acquire the * user's name and password. * @param sharedState shared <code>LoginModule</code> state. * @param options options specified in the login * <code>Configuration</code> for this particular * <code>LoginModule</code>. */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String,?> sharedState, Map<String,?> options) { this.subject = subject; this.callbackHandler = callbackHandler; this.sharedState = sharedState; this.options = options; // initialize any configured options tryFirstPass = "true".equalsIgnoreCase((String)options.get("tryFirstPass")); useFirstPass = "true".equalsIgnoreCase((String)options.get("useFirstPass")); storePass = "true".equalsIgnoreCase((String)options.get("storePass")); clearPass = "true".equalsIgnoreCase((String)options.get("clearPass")); passwordFile = (String)options.get("passwordFile"); passwordFileDisplayName = passwordFile; userSuppliedPasswordFile = true; // set the location of the password file if (passwordFile == null) { passwordFile = DEFAULT_PASSWORD_FILE_NAME; userSuppliedPasswordFile = false; try { System.getProperty("java.home"); hasJavaHomePermission = true; passwordFileDisplayName = passwordFile; } catch (SecurityException e) { hasJavaHomePermission = false; passwordFileDisplayName = ConnectorBootstrap.DefaultValues.PASSWORD_FILE_NAME; } } } /** * Begin user authentication (Authentication Phase 1). * * <p> Acquire the user's name and password and verify them against * the corresponding credentials from the password file. * * @return true always, since this <code>LoginModule</code> * should not be ignored. * @exception FailedLoginException if the authentication fails. * @exception LoginException if this <code>LoginModule</code> * is unable to perform the authentication. */ public boolean login() throws LoginException { try { loadPasswordFile(); } catch (IOException ioe) { LoginException le = new LoginException( "Error: unable to load the password file: " + passwordFileDisplayName); throw (LoginException) EnvHelp.initCause(le, ioe); } if (userCredentials == null) { throw new LoginException ("Error: unable to locate the users' credentials."); } if (logger.debugOn()) { logger.debug("login", "Using password file: " + passwordFileDisplayName); } // attempt the authentication if (tryFirstPass) { try { // attempt the authentication by getting the // username and password from shared state attemptAuthentication(true); // authentication succeeded succeeded = true; if (logger.debugOn()) { logger.debug("login", "Authentication using cached password has succeeded"); } return true; } catch (LoginException le) { // authentication failed -- try again below by prompting cleanState(); logger.debug("login", "Authentication using cached password has failed"); } } else if (useFirstPass) { try { // attempt the authentication by getting the // username and password from shared state attemptAuthentication(true); // authentication succeeded succeeded = true; if (logger.debugOn()) { logger.debug("login", "Authentication using cached password has succeeded"); } return true; } catch (LoginException le) { // authentication failed cleanState(); logger.debug("login", "Authentication using cached password has failed"); throw le; } } if (logger.debugOn()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -