< prev index next >

src/java.management/share/classes/com/sun/jmx/remote/security/FileLoginModule.java

Print this page


   1 /*
   2  * Copyright (c) 2004, 2008, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.jmx.remote.security;
  27 
  28 import com.sun.jmx.mbeanserver.GetPropertyAction;
  29 import com.sun.jmx.mbeanserver.Util;
  30 import java.io.BufferedInputStream;
  31 import java.io.File;
  32 import java.io.FileInputStream;
  33 import java.io.FilePermission;
  34 import java.io.IOException;
  35 import java.security.AccessControlException;
  36 import java.security.AccessController;
  37 import java.util.Arrays;
  38 import java.util.Hashtable;
  39 import java.util.Map;
  40 import java.util.Properties;
  41 
  42 import javax.security.auth.*;
  43 import javax.security.auth.callback.*;
  44 import javax.security.auth.login.*;
  45 import javax.security.auth.spi.*;
  46 import javax.management.remote.JMXPrincipal;
  47 
  48 import com.sun.jmx.remote.util.ClassLogger;
  49 import com.sun.jmx.remote.util.EnvHelp;
  50 
  51 /**
  52  * This {@link LoginModule} performs file-based authentication.
  53  *
  54  * <p> A supplied username and password is verified against the
  55  * corresponding user credentials stored in a designated password file.
  56  * If successful then a new {@link JMXPrincipal} is created with the
  57  * user's name and it is associated with the current {@link Subject}.
  58  * Such principals may be identified and granted management privileges in
  59  * the access control file for JMX remote management or in a Java security
  60  * policy.
  61  *
  62  * <p> The password file comprises a list of key-value pairs as specified in
  63  * {@link Properties}. The key represents a user's name and the value is its
  64  * associated cleartext password. By default, the following password file is
  65  * used:
  66  * <pre>
  67  *     ${java.home}/conf/management/jmxremote.password
  68  * </pre>
  69  * A different password file can be specified via the <code>passwordFile</code>
  70  * configuration option.
  71  *
  72  * <p> This module recognizes the following <code>Configuration</code> options:
  73  * <dl>
  74  * <dt> <code>passwordFile</code> </dt>
  75  * <dd> the path to an alternative password file. It is used instead of
  76  *      the default password file.</dd>
  77  *
  78  * <dt> <code>useFirstPass</code> </dt>
  79  * <dd> if <code>true</code>, this module retrieves the username and password
  80  *      from the module's shared state, using "javax.security.auth.login.name"
  81  *      and "javax.security.auth.login.password" as the respective keys. The
  82  *      retrieved values are used for authentication. If authentication fails,
  83  *      no attempt for a retry is made, and the failure is reported back to
  84  *      the calling application.</dd>
  85  *


  88  *      from the module's shared state, using "javax.security.auth.login.name"
  89  *       and "javax.security.auth.login.password" as the respective keys.  The
  90  *      retrieved values are used for authentication. If authentication fails,
  91  *      the module uses the CallbackHandler to retrieve a new username and
  92  *      password, and another attempt to authenticate is made. If the
  93  *      authentication fails, the failure is reported back to the calling
  94  *      application.</dd>
  95  *
  96  * <dt> <code>storePass</code> </dt>
  97  * <dd> if <code>true</code>, this module stores the username and password
  98  *      obtained from the CallbackHandler in the module's shared state, using
  99  *      "javax.security.auth.login.name" and
 100  *      "javax.security.auth.login.password" as the respective keys.  This is
 101  *      not performed if existing values already exist for the username and
 102  *      password in the shared state, or if authentication fails.</dd>
 103  *
 104  * <dt> <code>clearPass</code> </dt>
 105  * <dd> if <code>true</code>, this module clears the username and password
 106  *      stored in the module's shared state after both phases of authentication
 107  *      (login and commit) have completed.</dd>





 108  * </dl>
 109  */
 110 public class FileLoginModule implements LoginModule {
 111 
 112     private static final String PASSWORD_FILE_NAME = "jmxremote.password";
 113 
 114     // Location of the default password file
 115     private static final String DEFAULT_PASSWORD_FILE_NAME =
 116         AccessController.doPrivileged(new GetPropertyAction("java.home")) +
 117         File.separatorChar + "conf" +
 118         File.separatorChar + "management" + File.separatorChar +
 119         PASSWORD_FILE_NAME;
 120 
 121     // Key to retrieve the stored username
 122     private static final String USERNAME_KEY =
 123         "javax.security.auth.login.name";
 124 
 125     // Key to retrieve the stored password
 126     private static final String PASSWORD_KEY =
 127         "javax.security.auth.login.password";
 128 
 129     // Log messages
 130     private static final ClassLogger logger =
 131         new ClassLogger("javax.management.remote.misc", "FileLoginModule");
 132 
 133     // Configurable options
 134     private boolean useFirstPass = false;
 135     private boolean tryFirstPass = false;
 136     private boolean storePass = false;
 137     private boolean clearPass = false;

 138 
 139     // Authentication status
 140     private boolean succeeded = false;
 141     private boolean commitSucceeded = false;
 142 
 143     // Supplied username and password
 144     private String username;
 145     private char[] password;
 146     private JMXPrincipal user;
 147 
 148     // Initial state
 149     private Subject subject;
 150     private CallbackHandler callbackHandler;
 151     private Map<String, Object> sharedState;
 152     private Map<String, ?> options;
 153     private String passwordFile;
 154     private String passwordFileDisplayName;
 155     private boolean userSuppliedPasswordFile;
 156     private boolean hasJavaHomePermission;
 157     private Properties userCredentials;
 158 
 159     /**
 160      * Initialize this <code>LoginModule</code>.
 161      *
 162      * @param subject the <code>Subject</code> to be authenticated.
 163      * @param callbackHandler a <code>CallbackHandler</code> to acquire the
 164      *                  user's name and password.
 165      * @param sharedState shared <code>LoginModule</code> state.
 166      * @param options options specified in the login
 167      *                  <code>Configuration</code> for this particular
 168      *                  <code>LoginModule</code>.
 169      */
 170     public void initialize(Subject subject, CallbackHandler callbackHandler,
 171                            Map<String,?> sharedState,
 172                            Map<String,?> options)
 173     {
 174 
 175         this.subject = subject;
 176         this.callbackHandler = callbackHandler;
 177         this.sharedState = Util.cast(sharedState);
 178         this.options = options;
 179 
 180         // initialize any configured options
 181         tryFirstPass =
 182                 "true".equalsIgnoreCase((String)options.get("tryFirstPass"));
 183         useFirstPass =
 184                 "true".equalsIgnoreCase((String)options.get("useFirstPass"));
 185         storePass =
 186                 "true".equalsIgnoreCase((String)options.get("storePass"));
 187         clearPass =
 188                 "true".equalsIgnoreCase((String)options.get("clearPass"));


 189 
 190         passwordFile = (String)options.get("passwordFile");
 191         passwordFileDisplayName = passwordFile;
 192         userSuppliedPasswordFile = true;
 193 
 194         // set the location of the password file
 195         if (passwordFile == null) {
 196             passwordFile = DEFAULT_PASSWORD_FILE_NAME;
 197             userSuppliedPasswordFile = false;
 198             try {
 199                 System.getProperty("java.home");
 200                 hasJavaHomePermission = true;
 201                 passwordFileDisplayName = passwordFile;
 202             } catch (SecurityException e) {
 203                 hasJavaHomePermission = false;
 204                 passwordFileDisplayName = PASSWORD_FILE_NAME;
 205             }
 206         }
 207     }
 208 
 209     /**
 210      * Begin user authentication (Authentication Phase 1).
 211      *
 212      * <p> Acquire the user's name and password and verify them against
 213      * the corresponding credentials from the password file.
 214      *
 215      * @return true always, since this <code>LoginModule</code>
 216      *          should not be ignored.
 217      * @exception FailedLoginException if the authentication fails.
 218      * @exception LoginException if this <code>LoginModule</code>
 219      *          is unable to perform the authentication.
 220      */
 221     public boolean login() throws LoginException {
 222 
 223         try {
 224             loadPasswordFile();




 225         } catch (IOException ioe) {
 226             LoginException le = new LoginException(
 227                     "Error: unable to load the password file: " +
 228                     passwordFileDisplayName);
 229             throw EnvHelp.initCause(le, ioe);










 230         }
 231 
 232         if (userCredentials == null) {
 233             throw new LoginException
 234                 ("Error: unable to locate the users' credentials.");
 235         }
 236 
 237         if (logger.debugOn()) {
 238             logger.debug("login",
 239                     "Using password file: " + passwordFileDisplayName);
 240         }
 241 
 242         // attempt the authentication
 243         if (tryFirstPass) {
 244 
 245             try {
 246                 // attempt the authentication by getting the
 247                 // username and password from shared state
 248                 attemptAuthentication(true);
 249 
 250                 // authentication succeeded
 251                 succeeded = true;
 252                 if (logger.debugOn()) {
 253                     logger.debug("login",
 254                         "Authentication using cached password has succeeded");


 420         if (logger.debugOn()) {
 421             logger.debug("logout", "Subject is being logged out");
 422         }
 423 
 424         return true;
 425     }
 426 
 427     /**
 428      * Attempt authentication
 429      *
 430      * @param usePasswdFromSharedState a flag to tell this method whether
 431      *          to retrieve the password from the sharedState.
 432      */
 433     @SuppressWarnings("unchecked")  // sharedState used as Map<String,Object>
 434     private void attemptAuthentication(boolean usePasswdFromSharedState)
 435         throws LoginException {
 436 
 437         // get the username and password
 438         getUsernamePassword(usePasswdFromSharedState);
 439 
 440         String localPassword;
 441 
 442         // userCredentials is initialized in login()
 443         if (((localPassword = userCredentials.getProperty(username)) == null) ||
 444             (! localPassword.equals(new String(password)))) {
 445 
 446             // username not found or passwords do not match
 447             if (logger.debugOn()) {
 448                 logger.debug("login", "Invalid username or password");
 449             }
 450             throw new FailedLoginException("Invalid username or password");
 451         }
 452 
 453         // Save the username and password in the shared state
 454         // only if authentication succeeded
 455         if (storePass &&
 456             !sharedState.containsKey(USERNAME_KEY) &&
 457             !sharedState.containsKey(PASSWORD_KEY)) {
 458             sharedState.put(USERNAME_KEY, username);
 459             sharedState.put(PASSWORD_KEY, password);
 460         }
 461 
 462         // Create a new user principal
 463         user = new JMXPrincipal(username);
 464 
 465         if (logger.debugOn()) {
 466             logger.debug("login",
 467                 "User '" + username + "' successfully validated");
 468         }
 469     }
 470 
 471     /*
 472      * Read the password file.
 473      */
 474     private void loadPasswordFile() throws IOException {
 475         FileInputStream fis;
 476         try {
 477             fis = new FileInputStream(passwordFile);
 478         } catch (SecurityException e) {
 479             if (userSuppliedPasswordFile || hasJavaHomePermission) {
 480                 throw e;
 481             } else {
 482                 final FilePermission fp =
 483                         new FilePermission(passwordFileDisplayName, "read");
 484                 AccessControlException ace = new AccessControlException(
 485                         "access denied " + fp.toString());
 486                 ace.setStackTrace(e.getStackTrace());
 487                 throw ace;
 488             }
 489         }
 490         try {
 491             final BufferedInputStream bis = new BufferedInputStream(fis);
 492             try {
 493                 userCredentials = new Properties();
 494                 userCredentials.load(bis);
 495             } finally {
 496                 bis.close();
 497             }
 498         } finally {
 499             fis.close();
 500         }
 501     }
 502 
 503     /**
 504      * Get the username and password.
 505      * This method does not return any value.
 506      * Instead, it sets global name and password variables.
 507      *
 508      * <p> Also note that this method will set the username and password
 509      * values in the shared state in case subsequent LoginModules
 510      * want to use them via use/tryFirstPass.
 511      *
 512      * @param usePasswdFromSharedState boolean that tells this method whether
 513      *          to retrieve the password from the sharedState.
 514      */
 515     private void getUsernamePassword(boolean usePasswdFromSharedState)
 516         throws LoginException {
 517 
 518         if (usePasswdFromSharedState) {
 519             // use the password saved by the first module in the stack


   1 /*
   2  * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.jmx.remote.security;
  27 
  28 import com.sun.jmx.mbeanserver.GetPropertyAction;
  29 import com.sun.jmx.mbeanserver.Util;

  30 import java.io.File;

  31 import java.io.FilePermission;
  32 import java.io.IOException;
  33 import java.security.AccessControlException;
  34 import java.security.AccessController;
  35 import java.util.Arrays;

  36 import java.util.Map;

  37 
  38 import javax.security.auth.*;
  39 import javax.security.auth.callback.*;
  40 import javax.security.auth.login.*;
  41 import javax.security.auth.spi.*;
  42 import javax.management.remote.JMXPrincipal;
  43 
  44 import com.sun.jmx.remote.util.ClassLogger;
  45 import com.sun.jmx.remote.util.EnvHelp;
  46 
  47 /**
  48  * This {@link LoginModule} performs file-based authentication.
  49  *
  50  * <p> A supplied username and password is verified against the
  51  * corresponding user credentials stored in a designated password file.
  52  * If successful then a new {@link JMXPrincipal} is created with the
  53  * user's name and it is associated with the current {@link Subject}.
  54  * Such principals may be identified and granted management privileges in
  55  * the access control file for JMX remote management or in a Java security
  56  * policy.
  57  *
  58  * By default, the following password file is used:



  59  * <pre>
  60  *     ${java.home}/conf/management/jmxremote.password
  61  * </pre>
  62  * A different password file can be specified via the <code>passwordFile</code>
  63  * configuration option.
  64  *
  65  * <p> This module recognizes the following <code>Configuration</code> options:
  66  * <dl>
  67  * <dt> <code>passwordFile</code> </dt>
  68  * <dd> the path to an alternative password file. It is used instead of
  69  *      the default password file.</dd>
  70  *
  71  * <dt> <code>useFirstPass</code> </dt>
  72  * <dd> if <code>true</code>, this module retrieves the username and password
  73  *      from the module's shared state, using "javax.security.auth.login.name"
  74  *      and "javax.security.auth.login.password" as the respective keys. The
  75  *      retrieved values are used for authentication. If authentication fails,
  76  *      no attempt for a retry is made, and the failure is reported back to
  77  *      the calling application.</dd>
  78  *


  81  *      from the module's shared state, using "javax.security.auth.login.name"
  82  *       and "javax.security.auth.login.password" as the respective keys.  The
  83  *      retrieved values are used for authentication. If authentication fails,
  84  *      the module uses the CallbackHandler to retrieve a new username and
  85  *      password, and another attempt to authenticate is made. If the
  86  *      authentication fails, the failure is reported back to the calling
  87  *      application.</dd>
  88  *
  89  * <dt> <code>storePass</code> </dt>
  90  * <dd> if <code>true</code>, this module stores the username and password
  91  *      obtained from the CallbackHandler in the module's shared state, using
  92  *      "javax.security.auth.login.name" and
  93  *      "javax.security.auth.login.password" as the respective keys.  This is
  94  *      not performed if existing values already exist for the username and
  95  *      password in the shared state, or if authentication fails.</dd>
  96  *
  97  * <dt> <code>clearPass</code> </dt>
  98  * <dd> if <code>true</code>, this module clears the username and password
  99  *      stored in the module's shared state after both phases of authentication
 100  *      (login and commit) have completed.</dd>
 101  *
 102  * <dt> <code>hashPasswords</code> </dt>
 103  * <dd> if <code>true</code>, this module replaces each clear text passwords
 104  *      with its hash, if present. </dd>
 105  *
 106  * </dl>
 107  */
 108 public class FileLoginModule implements LoginModule {
 109 
 110     private static final String PASSWORD_FILE_NAME = "jmxremote.password";
 111 
 112     // Location of the default password file
 113     private static final String DEFAULT_PASSWORD_FILE_NAME =
 114         AccessController.doPrivileged(new GetPropertyAction("java.home")) +
 115         File.separatorChar + "conf" +
 116         File.separatorChar + "management" + File.separatorChar +
 117         PASSWORD_FILE_NAME;
 118 
 119     // Key to retrieve the stored username
 120     private static final String USERNAME_KEY =
 121         "javax.security.auth.login.name";
 122 
 123     // Key to retrieve the stored password
 124     private static final String PASSWORD_KEY =
 125         "javax.security.auth.login.password";
 126 
 127     // Log messages
 128     private static final ClassLogger logger =
 129         new ClassLogger("javax.management.remote.misc", "FileLoginModule");
 130 
 131     // Configurable options
 132     private boolean useFirstPass = false;
 133     private boolean tryFirstPass = false;
 134     private boolean storePass = false;
 135     private boolean clearPass = false;
 136     private boolean hashPasswords = false;
 137 
 138     // Authentication status
 139     private boolean succeeded = false;
 140     private boolean commitSucceeded = false;
 141 
 142     // Supplied username and password
 143     private String username;
 144     private char[] password;
 145     private JMXPrincipal user;
 146 
 147     // Initial state
 148     private Subject subject;
 149     private CallbackHandler callbackHandler;
 150     private Map<String, Object> sharedState;
 151     private Map<String, ?> options;
 152     private String passwordFile;
 153     private String passwordFileDisplayName;
 154     private boolean userSuppliedPasswordFile;
 155     private boolean hasJavaHomePermission;
 156     private HashedPasswordManager hashPwdMgr;
 157 
 158     /**
 159      * Initialize this <code>LoginModule</code>.
 160      *
 161      * @param subject the <code>Subject</code> to be authenticated.
 162      * @param callbackHandler a <code>CallbackHandler</code> to acquire the
 163      *                  user's name and password.
 164      * @param sharedState shared <code>LoginModule</code> state.
 165      * @param options options specified in the login
 166      *                  <code>Configuration</code> for this particular
 167      *                  <code>LoginModule</code>.
 168      */
 169     public void initialize(Subject subject, CallbackHandler callbackHandler,
 170                            Map<String,?> sharedState,
 171                            Map<String,?> options)
 172     {
 173 
 174         this.subject = subject;
 175         this.callbackHandler = callbackHandler;
 176         this.sharedState = Util.cast(sharedState);
 177         this.options = options;
 178 
 179         // initialize any configured options
 180         tryFirstPass =
 181                 "true".equalsIgnoreCase((String)options.get("tryFirstPass"));
 182         useFirstPass =
 183                 "true".equalsIgnoreCase((String)options.get("useFirstPass"));
 184         storePass =
 185                 "true".equalsIgnoreCase((String)options.get("storePass"));
 186         clearPass =
 187                 "true".equalsIgnoreCase((String)options.get("clearPass"));
 188         hashPasswords =
 189                 "true".equalsIgnoreCase((String)options.get("hashPasswords"));
 190 
 191         passwordFile = (String)options.get("passwordFile");
 192         passwordFileDisplayName = passwordFile;
 193         userSuppliedPasswordFile = true;
 194 
 195         // set the location of the password file
 196         if (passwordFile == null) {
 197             passwordFile = DEFAULT_PASSWORD_FILE_NAME;
 198             userSuppliedPasswordFile = false;
 199             try {
 200                 System.getProperty("java.home");
 201                 hasJavaHomePermission = true;
 202                 passwordFileDisplayName = passwordFile;
 203             } catch (SecurityException e) {
 204                 hasJavaHomePermission = false;
 205                 passwordFileDisplayName = PASSWORD_FILE_NAME;
 206             }
 207         }
 208     }
 209 
 210     /**
 211      * Begin user authentication (Authentication Phase 1).
 212      *
 213      * <p> Acquire the user's name and password and verify them against
 214      * the corresponding credentials from the password file.
 215      *
 216      * @return true always, since this <code>LoginModule</code>
 217      *          should not be ignored.
 218      * @exception FailedLoginException if the authentication fails.
 219      * @exception LoginException if this <code>LoginModule</code>
 220      *          is unable to perform the authentication.
 221      */
 222     public boolean login() throws LoginException {
 223 
 224         try {
 225             if(hashPwdMgr == null) {
 226                 hashPwdMgr = new HashedPasswordManager(passwordFile, hashPasswords);
 227             } else {
 228                 hashPwdMgr.loadPasswords();
 229             }
 230         } catch (IOException ioe) {
 231             LoginException le = new LoginException(
 232                     "Error: unable to load the password file: " +
 233                     passwordFileDisplayName);
 234             throw EnvHelp.initCause(le, ioe);
 235         } catch (SecurityException e) {
 236             if (userSuppliedPasswordFile || hasJavaHomePermission) {
 237                 throw e;
 238             } else {
 239                 final FilePermission fp =
 240                         new FilePermission(passwordFileDisplayName, "read");
 241                 AccessControlException ace = new AccessControlException(
 242                         "access denied " + fp.toString());
 243                 ace.setStackTrace(e.getStackTrace());
 244                 throw ace;
 245             }




 246         }
 247 
 248         if (logger.debugOn()) {
 249             logger.debug("login",
 250                     "Using password file: " + passwordFileDisplayName);
 251         }
 252 
 253         // attempt the authentication
 254         if (tryFirstPass) {
 255 
 256             try {
 257                 // attempt the authentication by getting the
 258                 // username and password from shared state
 259                 attemptAuthentication(true);
 260 
 261                 // authentication succeeded
 262                 succeeded = true;
 263                 if (logger.debugOn()) {
 264                     logger.debug("login",
 265                         "Authentication using cached password has succeeded");


 431         if (logger.debugOn()) {
 432             logger.debug("logout", "Subject is being logged out");
 433         }
 434 
 435         return true;
 436     }
 437 
 438     /**
 439      * Attempt authentication
 440      *
 441      * @param usePasswdFromSharedState a flag to tell this method whether
 442      *          to retrieve the password from the sharedState.
 443      */
 444     @SuppressWarnings("unchecked")  // sharedState used as Map<String,Object>
 445     private void attemptAuthentication(boolean usePasswdFromSharedState)
 446         throws LoginException {
 447 
 448         // get the username and password
 449         getUsernamePassword(usePasswdFromSharedState);
 450 
 451         if (!hashPwdMgr.authenticate(username, new String(password))) {





 452             // username not found or passwords do not match
 453             if (logger.debugOn()) {
 454                 logger.debug("login", "Invalid username or password");
 455             }
 456             throw new FailedLoginException("Invalid username or password");
 457         }
 458 
 459         // Save the username and password in the shared state
 460         // only if authentication succeeded
 461         if (storePass &&
 462             !sharedState.containsKey(USERNAME_KEY) &&
 463             !sharedState.containsKey(PASSWORD_KEY)) {
 464             sharedState.put(USERNAME_KEY, username);
 465             sharedState.put(PASSWORD_KEY, password);
 466         }
 467 
 468         // Create a new user principal
 469         user = new JMXPrincipal(username);
 470 
 471         if (logger.debugOn()) {
 472             logger.debug("login",
 473                 "User '" + username + "' successfully validated");
































 474         }
 475     }
 476 
 477     /**
 478      * Get the username and password.
 479      * This method does not return any value.
 480      * Instead, it sets global name and password variables.
 481      *
 482      * <p> Also note that this method will set the username and password
 483      * values in the shared state in case subsequent LoginModules
 484      * want to use them via use/tryFirstPass.
 485      *
 486      * @param usePasswdFromSharedState boolean that tells this method whether
 487      *          to retrieve the password from the sharedState.
 488      */
 489     private void getUsernamePassword(boolean usePasswdFromSharedState)
 490         throws LoginException {
 491 
 492         if (usePasswdFromSharedState) {
 493             // use the password saved by the first module in the stack


< prev index next >