keystoreloginmodule.java
来自「java jdk 1.4的源码」· Java 代码 · 共 696 行 · 第 1/2 页
JAVA
696 行
/* * @(#)KeyStoreLoginModule.java 1.13 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.security.auth.module;import javax.security.auth.x500.X500Principal;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.PushbackInputStream;import java.net.MalformedURLException;import java.net.URL;import java.security.GeneralSecurityException;import java.security.Key;import java.security.KeyStore;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.NoSuchProviderException;import java.security.Principal;import java.security.PrivateKey;import java.security.UnrecoverableKeyException;import java.security.cert.*;import java.security.cert.X509Certificate;import java.util.Arrays;import java.util.Iterator;import java.util.LinkedList;import java.util.Map;import java.util.ResourceBundle;import javax.security.auth.Destroyable;import javax.security.auth.DestroyFailedException;import javax.security.auth.Subject;import javax.security.auth.x500.*;import javax.security.auth.Subject;import javax.security.auth.x500.*;import javax.security.auth.callback.Callback;import javax.security.auth.callback.CallbackHandler;import javax.security.auth.callback.ConfirmationCallback;import javax.security.auth.callback.NameCallback;import javax.security.auth.callback.PasswordCallback;import javax.security.auth.callback.TextOutputCallback;import javax.security.auth.callback.UnsupportedCallbackException;import javax.security.auth.login.FailedLoginException;import javax.security.auth.login.LoginException;import javax.security.auth.spi.LoginModule;import sun.security.util.AuthResources;/** * Provides a JAAS login module that prompts for a key store alias and * populates the subject with the alias's principal and credentials. Stores * an <code>X500Principal</code> for the subject distinguished name of the * first certificate in the alias's credentials in the subject's principals, * the alias's certificate path in the subject's public credentials, and a * <code>X500PrivateCredential</code> whose certificate is the first * certificate in the alias's certificate path and whose private key is the * alias's private key in the subject's private credentials. <p> * * Recognizes the following options in the JAAS authentication policy file: * <dl> * * <dt> <code>keyStoreURL</code> </dt> * <dd> A URL that specifies the location of the key store file. Defaults to * the .keystore file in the directory specified by the * <code>java.home</code> system property. </dd> * * <dt> <code>keyStoreType</code> </dt> * <dd> The key store type. If not specified, defaults to the result of * calling <code>KeyStore.getDefaultType()</code>. </dd> * * <dt> <code>keyStoreProvider</code> </dt> * <dd> The key store provider. If not specified, uses the standard search * order to find the provider. </dd> * * <dt> <code>keyStoreAlias</code> </dt> * <dd> The alias in the key store to login as. Required when no callback * handler is provided. No default value. </dd> * * <dt> <code>keyStorePasswordURL</code> </dt> * <dd> A URL that specifies the location of the key store password. Required * when no callback handler is provided. No default value. </dd> * * <dt> <code>privateKeyPasswordURL</code> </dt> * <dd> A URL that specifies the location of the specific private key password * needed to access the private key for this alias. * The keystore password * is used if this value is not specified. </dd> * </dl> */public class KeyStoreLoginModule implements LoginModule { static final java.util.ResourceBundle rb = java.util.ResourceBundle.getBundle("sun.security.util.AuthResources"); /* -- Fields -- */ private static final int UNINITIALIZED = 0; private static final int INITIALIZED = 1; private static final int AUTHENTICATED = 2; private static final int LOGGED_IN = 3; private Subject subject; private CallbackHandler callbackHandler; private Map sharedState; private Map options; private char[] keyStorePassword; private char[] privateKeyPassword; private String keyStoreURL; private String keyStoreType; private String keyStoreProvider; private String keyStoreAlias; private String keyStorePasswordURL; private String privateKeyPasswordURL; private boolean debug; private javax.security.auth.x500.X500Principal principal; private Certificate[] fromKeyStore; private java.security.cert.CertPath certP = null; private X500PrivateCredential privateCredential; private int status = UNINITIALIZED; /* -- Methods -- */ /** * Initialize this <code>LoginModule</code>. * * <p> * * @param subject the <code>Subject</code> to be authenticated. <p> * * @param callbackHandler a <code>CallbackHandler</code> for communicating * with the end user (prompting for usernames and * passwords, for example). <p> * * @param sharedState shared <code>LoginModule</code> state. <p> * * @param options options specified in the login * <code>Configuration</code> for this particular * <code>LoginModule</code>. */ public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options) { this.subject = subject; this.callbackHandler = callbackHandler; this.sharedState = sharedState; this.options = options; processOptions(); status = INITIALIZED; } private void processOptions() { keyStoreURL = (String) options.get("keyStoreURL"); if (keyStoreURL == null) { keyStoreURL = "file:" + System.getProperty("user.home").replace( File.separatorChar, '/') + '/' + ".keystore"; } keyStoreType = (String) options.get("keyStoreType"); if (keyStoreType == null) { keyStoreType = KeyStore.getDefaultType(); } keyStoreProvider = (String) options.get("keyStoreProvider"); keyStoreAlias = (String) options.get("keyStoreAlias"); keyStorePasswordURL = (String) options.get("keyStorePasswordURL"); privateKeyPasswordURL = (String) options.get("privateKeyPasswordURL"); debug = "true".equalsIgnoreCase((String) options.get("debug")); if (debug) debugPrint("keyStoreURL=" + keyStoreURL + " keyStoreAlias=" + keyStoreAlias + " keyStorePasswordURL=" + keyStorePasswordURL + " privateKeyPasswordURL=" + privateKeyPasswordURL); } /** * Authenticate the user . * * <p> Prompt the user for the Keystore alias and the password. Retrieve * the alias's principal and credentials from the Keystore. * * <p> * * @exception FailedLoginException if the authentication fails. <p> * * @return true in all cases (this <code>LoginModule</code> * should not be ignored). */ public boolean login() throws LoginException { switch (status) { case UNINITIALIZED: default: throw new LoginException("The login module is not initialized"); case INITIALIZED: case AUTHENTICATED: getAliasAndPassword(); getKeyStoreInfo(); status = AUTHENTICATED; return true; case LOGGED_IN: return true; } } /** Get the alias and passwords to use for looking up in the KeyStore. */ private void getAliasAndPassword() throws LoginException { if (callbackHandler == null) { /* * No callback handler. Check for alias and password files * specified in the options. */ if (keyStoreAlias == null) { throw new LoginException( "Need to specify an alias option to use " + "KeyStoreLoginModule non-interactively."); } if (keyStorePasswordURL == null) { throw new LoginException( "Need to specify passwordFile option to use " + "KeyStoreLoginModule non-interactively."); } try { InputStream in = new URL(keyStorePasswordURL).openStream(); keyStorePassword = readPassword(in); in.close(); } catch (IOException e) { throw new LoginException( "Problem accessing keystore password \"" + keyStorePasswordURL + "\": " + e); } if (privateKeyPasswordURL == null) { privateKeyPassword = keyStorePassword; } else { try { InputStream in = new URL(privateKeyPasswordURL).openStream(); privateKeyPassword = readPassword(in); in.close(); } catch (IOException e) { throw new LoginException( "Problem accessing private key password \"" + privateKeyPasswordURL + "\": " + e); } } } else { TextOutputCallback bannerCallback = new TextOutputCallback( TextOutputCallback.INFORMATION, rb.getString("Please login to keystore")); NameCallback aliasCallback; if (keyStoreAlias == null || keyStoreAlias.length() == 0) { aliasCallback = new NameCallback( rb.getString("Keystore alias: ")); } else { aliasCallback = new NameCallback(rb.getString("Keystore alias: "), keyStoreAlias); } PasswordCallback keyStorePasswordCallback = new PasswordCallback(rb.getString("Keystore password: "), false); PasswordCallback privateKeyPasswordCallback = new PasswordCallback( rb.getString("Private key password (optional): "), false); ConfirmationCallback confirmationCallback = new ConfirmationCallback( ConfirmationCallback.INFORMATION, ConfirmationCallback.OK_CANCEL_OPTION, ConfirmationCallback.OK); try { callbackHandler.handle( new Callback[] { bannerCallback, aliasCallback, keyStorePasswordCallback, privateKeyPasswordCallback, confirmationCallback }); } catch (IOException e) { throw new LoginException( "Exception while getting keystore alias and password: " + e); } catch (UnsupportedCallbackException e) { throw new LoginException( "Error: " + e.getCallback().toString() + " is not available to retrieve authentication " + " information from the user"); } int confirmationResult = confirmationCallback.getSelectedIndex(); if (confirmationResult == ConfirmationCallback.CANCEL) { throw new LoginException("Login cancelled"); } keyStoreAlias = aliasCallback.getName(); char[] tmpPassword = keyStorePasswordCallback.getPassword(); if (tmpPassword == null) { /* Treat a NULL password as an empty password */ tmpPassword = new char[0]; } keyStorePassword = new char[tmpPassword.length]; System.arraycopy(tmpPassword, 0, keyStorePassword, 0, tmpPassword.length); keyStorePasswordCallback.clearPassword(); tmpPassword = privateKeyPasswordCallback.getPassword(); if (tmpPassword == null || tmpPassword.length == 0) { /* * Use keystore password if no private key password is * specified. */ privateKeyPassword = keyStorePassword; } else { privateKeyPassword = new char[tmpPassword.length]; System.arraycopy(tmpPassword, 0, privateKeyPassword, 0, tmpPassword.length); for (int i=0; i <tmpPassword.length ; i++) tmpPassword[0] = ' '; tmpPassword=null; privateKeyPasswordCallback.clearPassword(); } if (debug)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?