keystoreloginmodule.java

来自「java jdk 1.4的源码」· Java 代码 · 共 696 行 · 第 1/2 页

JAVA
696
字号
		debugPrint("alias=" + keyStoreAlias);	}    }    /** Get the credentials from the KeyStore. */    private void getKeyStoreInfo() throws LoginException {	/* Get KeyStore instance */	KeyStore keyStore;	try {	    if (keyStoreProvider == null) {		keyStore = KeyStore.getInstance(keyStoreType);	    } else {		keyStore =		    KeyStore.getInstance(keyStoreType, keyStoreProvider);	    }	} catch (KeyStoreException e) {	    throw new LoginException(		"The specified keystore type was not available: " + e);	} catch (NoSuchProviderException e) {	    throw new LoginException(		"The specified keystore provider was not available: " + e);	}	/* Load KeyStore contents from file */	try {	    InputStream in = new URL(keyStoreURL).openStream();	    keyStore.load(in, keyStorePassword);	    in.close();	} catch (MalformedURLException e) {	    throw new LoginException("Incorrect keyStoreURL option: " + e);	} catch (GeneralSecurityException e) {	    throw new LoginException("Error initializing keystore: " + e);	} catch (IOException e) {	    throw new LoginException("Error initializing keystore: " + e);	}	/* Get certificate chain and create a certificate path */	try {	    fromKeyStore =		keyStore.getCertificateChain(keyStoreAlias);	    if (fromKeyStore == null		|| fromKeyStore.length == 0		|| !(fromKeyStore[0] instanceof X509Certificate))	    {		throw new FailedLoginException(		    "Unable to find X.509 certificate chain in keystore");	    } else {		LinkedList certList = new LinkedList();		for (int i=0; i < fromKeyStore.length; i++) {		    certList.add(fromKeyStore[i]);		}		CertificateFactory certF= 		    CertificateFactory.getInstance("X.509");		certP = 		    certF.generateCertPath(certList);		    }	} catch (KeyStoreException e) {	    throw new LoginException("Error using keystore: " + e);	} catch (CertificateException ce) {	    throw new LoginException("Error: X.509 Certificate type unavailable: " + ce);	}	/* Get principal and keys */	try {	    X509Certificate certificate = (X509Certificate)fromKeyStore[0];	    principal = new javax.security.auth.x500.X500Principal		(certificate.getSubjectDN().getName());	    Key privateKey =		keyStore.getKey(keyStoreAlias, privateKeyPassword);	    if (privateKey == null		|| !(privateKey instanceof PrivateKey))	    {		throw new FailedLoginException(		    "Unable to recover key from keystore");	    }	    privateCredential = new X500PrivateCredential(		certificate, (PrivateKey) privateKey, keyStoreAlias);	} catch (KeyStoreException e) {	    throw new LoginException("Error using keystore: " + e);	} catch (NoSuchAlgorithmException e) {	    throw new LoginException("Error using keystore: " + e);	} catch (UnrecoverableKeyException e) {	    throw new FailedLoginException(					   "Unable to recover key from " +					   "keystore: " + e);	}	if (debug) {	    debugPrint("principal=" + principal +		       "\n certificate="		       + privateCredential.getCertificate() +		       "\n alias =" + privateCredential.getAlias());	}    }    /**     * Abstract method to commit the authentication process (phase 2).     *     * <p> This method is called if the LoginContext's     * overall authentication succeeded     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules     * succeeded).     *     * <p> If this LoginModule's own authentication attempt     * succeeded (checked by retrieving the private state saved by the     * <code>login</code> method), then this method associates a     * <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.  If this LoginModule's own     * authentication attempted failed, then this method removes     * any state that was originally saved.     *     * <p>     *     * @exception LoginException if the commit fails     *     * @return true if this LoginModule's own login and commit     *		attempts succeeded, or false otherwise.     */    public boolean commit() throws LoginException {	switch (status) {	case UNINITIALIZED:	default:	    throw new LoginException("The login module is not initialized");	case INITIALIZED:	    logoutInternal();	    throw new LoginException("Authentication failed");	case AUTHENTICATED:	    if (commitInternal()) {		return true;	    } else {		logoutInternal();		throw new LoginException("Unable to retrieve certificates");	    }	case LOGGED_IN:	    return true;	}    }    private boolean commitInternal() throws LoginException {	/* If the subject is not readonly add to the principal and credentials	 * set; otherwise just return true	 */	if (subject.isReadOnly()) {	    throw new LoginException ("Subject is set readonly");	} else {	    subject.getPrincipals().add(principal);	    subject.getPublicCredentials().add(certP);	    subject.getPrivateCredentials().add(privateCredential);	    status = LOGGED_IN;	    return true;	}    }    /**     * <p> This method is called if the LoginContext's     * overall authentication failed.     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules     * did not succeed).     *     * <p> If this LoginModule's own authentication attempt     * succeeded (checked by retrieving the private state saved by the     * <code>login</code> and <code>commit</code> methods),     * then this method cleans up any state that was originally saved.     *     * <p>     *     * @exception LoginException if the abort fails.     *     * @return false if this LoginModule's own login and/or commit attempts     *		failed, and true otherwise.     */	    public boolean abort() throws LoginException {	switch (status) {	case UNINITIALIZED:	default:	    return false;	case INITIALIZED:	    return false;	case AUTHENTICATED:	    logoutInternal();	    return true;	case LOGGED_IN:	    logoutInternal();	    return true;	}    }    /**     * Logout a user.     *     * <p> This method removes the Principals, public credentials and the     * private credentials that were added by the <code>commit</code> method.     *     * <p>     *     * @exception LoginException if the logout fails.     *     * @return true in all cases since this <code>LoginModule</code>     *		should not be ignored.     */    public boolean logout() throws LoginException {	if (debug)	    debugPrint("Entering logout " + status);	switch (status) {	case UNINITIALIZED:	    throw new LoginException		("The login module is not initialized");	case INITIALIZED:	case AUTHENTICATED:	default:	   // impossible for LoginModule to be in AUTHENTICATED 	   // state	   // assert status != AUTHENTICATED;	    return false;	case LOGGED_IN:	    logoutInternal();	    return true;	}    }    private void logoutInternal() throws LoginException {	if (debug)	    debugPrint("Entering logoutInternal");	Arrays.fill(keyStorePassword, '\0');	keyStorePassword = null;	Arrays.fill(privateKeyPassword, '\0');	privateKeyPassword = null;	if (subject.isReadOnly()) {	    // attempt to destroy the private credential	    // even if the Subject is read-only	    principal = null;	    certP = null;	    status = INITIALIZED;	    // destroy the private credential	    Iterator it = subject.getPrivateCredentials().iterator();	    while (it.hasNext()) {		Object obj = it.next();		if (privateCredential.equals(obj)) {		    privateCredential = null;		    try {			((Destroyable)obj).destroy();			if (debug)			    debugPrint("Destroyed private credential, " +				       obj.getClass().getName());			break;		    } catch (DestroyFailedException dfe) {			throw new LoginException			    ("Unable to destroy private credential, " 			     + obj.getClass().getName()			     + ": " + dfe.getMessage());		    }		}	    }	    	    // throw an exception because we can not remove	    // the principal and public credential from this	    // read-only Subject	    throw new LoginException		("Unable to remove Principal (" 		 + "X500Principal "		 + ") and public credential (certificatepath) "		 + "from read-only Subject");	}	if (principal != null) {	    subject.getPrincipals().remove(principal);	    principal = null;	}	if (certP != null) {	    subject.getPublicCredentials().remove(certP);	    certP = null;	}	if (privateCredential != null) {	    subject.getPrivateCredentials().remove(privateCredential);	    privateCredential = null;	}	status = INITIALIZED;    }    /** Reads user password from given input stream. */    private char[] readPassword(InputStream in) throws IOException {	char[] lineBuffer;	char[] buf;	int i;	buf = lineBuffer = new char[128];	int room = buf.length;	int offset = 0;	int c;	boolean done = false;	while (!done) {	    switch (c = in.read()) {	      case -1: 	      case '\n':		  done = true;		  break;	      case '\r':		int c2 = in.read();		if ((c2 != '\n') && (c2 != -1)) {		    if (!(in instanceof PushbackInputStream)) {			in = new PushbackInputStream(in);		    }		    ((PushbackInputStream)in).unread(c2);		} else {		    done = true;		    break;		}	      default:		if (--room < 0) {		    buf = new char[offset + 128];		    room = buf.length - offset - 1;		    System.arraycopy(lineBuffer, 0, buf, 0, offset);		    Arrays.fill(lineBuffer, ' ');		    lineBuffer = buf;		}		buf[offset++] = (char) c;		break;	    }	}	if (offset == 0) {	    return null;	}	char[] ret = new char[offset];	System.arraycopy(buf, 0, ret, 0, offset);	Arrays.fill(buf, ' ');	return ret;    }    private void debugPrint(String message) {	// we should switch to logging API	    System.err.println("Debug KeyStoreLoginModule: " + message);    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?