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 + -
显示快捷键?