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