jndiloginmodule.java
来自「JAVA 所有包」· Java 代码 · 共 752 行 · 第 1/2 页
JAVA
752 行
if (debug) { System.out.println("\t\t[JndiLoginModule]: " + "added UnixPrincipal,"); System.out.println("\t\t\t\tUnixNumericUserPrincipal,"); System.out.println("\t\t\t\tUnixNumericGroupPrincipal(s),"); System.out.println("\t\t\t to Subject"); } } // in any case, clean out state cleanState(); commitSucceeded = true; 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 { if (debug) System.out.println("\t\t[JndiLoginModule]: " + "aborted authentication failed"); if (succeeded == false) { return false; } else if (succeeded == true && commitSucceeded == false) { // Clean out state succeeded = false; cleanState(); userPrincipal = null; UIDPrincipal = null; GIDPrincipal = null; supplementaryGroups = new LinkedList(); } else { // overall authentication succeeded and commit succeeded, // but someone else's commit failed logout(); } return true; } /** * Logout a user. * * <p> This method removes the Principals * 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 (subject.isReadOnly()) { cleanState(); throw new LoginException ("Subject is Readonly"); } subject.getPrincipals().remove(userPrincipal); subject.getPrincipals().remove(UIDPrincipal); subject.getPrincipals().remove(GIDPrincipal); for (int i = 0; i < supplementaryGroups.size(); i++) { subject.getPrincipals().remove ((UnixNumericGroupPrincipal)supplementaryGroups.get(i)); } // clean out state cleanState(); succeeded = false; commitSucceeded = false; userPrincipal = null; UIDPrincipal = null; GIDPrincipal = null; supplementaryGroups = new LinkedList(); if (debug) { System.out.println("\t\t[JndiLoginModule]: " + "logged out Subject"); } return true; } /** * Attempt authentication * * <p> * * @param getPasswdFromSharedState boolean that tells this method whether * to retrieve the password from the sharedState. */ private void attemptAuthentication(boolean getPasswdFromSharedState) throws LoginException { String encryptedPassword = null; // first get the username and password getUsernamePassword(getPasswdFromSharedState); try { // get the user's passwd entry from the user provider URL InitialContext iCtx = new InitialContext(); ctx = (DirContext)iCtx.lookup(userProvider); /* SearchControls controls = new SearchControls (SearchControls.ONELEVEL_SCOPE, 0, 5000, new String[] { USER_PWD }, false, false); */ SearchControls controls = new SearchControls(); NamingEnumeration ne = ctx.search("", "(uid=" + username + ")", controls); if (ne.hasMore()) { SearchResult result = (SearchResult)ne.next(); Attributes attributes = result.getAttributes(); // get the password // this module works only if the LDAP directory server // is configured to permit read access to the userPassword // attribute. The directory administrator need to grant // this access. // // A workaround would be to make the server do authentication // by setting the Context.SECURITY_PRINCIPAL // and Context.SECURITY_CREDENTIALS property. // However, this would make it not work with systems that // don't do authentication at the server (like NIS). // // Setting the SECURITY_* properties and using "simple" // authentication for LDAP is recommended only for secure // channels. For nonsecure channels, SSL is recommended. Attribute pwd = attributes.get(USER_PWD); String encryptedPwd = new String((byte[])pwd.get(), "UTF8"); encryptedPassword = encryptedPwd.substring(CRYPT.length()); // check the password if (verifyPassword (encryptedPassword, new String(password)) == true) { // authentication succeeded if (debug) System.out.println("\t\t[JndiLoginModule] " + "attemptAuthentication() succeeded"); } else { // authentication failed if (debug) System.out.println("\t\t[JndiLoginModule] " + "attemptAuthentication() failed"); throw new FailedLoginException("Login incorrect"); } // save input as shared state only if // authentication succeeded if (storePass && !sharedState.containsKey(NAME) && !sharedState.containsKey(PWD)) { sharedState.put(NAME, username); sharedState.put(PWD, password); } // create the user principal userPrincipal = new UnixPrincipal(username); // get the UID Attribute uid = attributes.get(USER_UID); String uidNumber = (String)uid.get(); UIDPrincipal = new UnixNumericUserPrincipal(uidNumber); if (debug && uidNumber != null) { System.out.println("\t\t[JndiLoginModule] " + "user: '" + username + "' has UID: " + uidNumber); } // get the GID Attribute gid = attributes.get(USER_GID); String gidNumber = (String)gid.get(); GIDPrincipal = new UnixNumericGroupPrincipal (gidNumber, true); if (debug && gidNumber != null) { System.out.println("\t\t[JndiLoginModule] " + "user: '" + username + "' has GID: " + gidNumber); } // get the supplementary groups from the group provider URL ctx = (DirContext)iCtx.lookup(groupProvider); ne = ctx.search("", new BasicAttributes("memberUid", username)); while (ne.hasMore()) { result = (SearchResult)ne.next(); attributes = result.getAttributes(); gid = attributes.get(GROUP_ID); String suppGid = (String)gid.get(); if (!gidNumber.equals(suppGid)) { UnixNumericGroupPrincipal suppPrincipal = new UnixNumericGroupPrincipal(suppGid, false); supplementaryGroups.add(suppPrincipal); if (debug && suppGid != null) { System.out.println("\t\t[JndiLoginModule] " + "user: '" + username + "' has Supplementary Group: " + suppGid); } } } } else { // bad username if (debug) { System.out.println("\t\t[JndiLoginModule]: User not found"); } throw new FailedLoginException("User not found"); } } catch (NamingException ne) { // bad username if (debug) { System.out.println("\t\t[JndiLoginModule]: User not found"); ne.printStackTrace(); } throw new FailedLoginException("User not found"); } catch (java.io.UnsupportedEncodingException uee) { // password stored in incorrect format if (debug) { System.out.println("\t\t[JndiLoginModule]: " + "password incorrectly encoded"); uee.printStackTrace(); } throw new LoginException("Login failure due to incorrect " + "password encoding in the password database"); } // authentication succeeded } /** * Get the username and password. * This method does not return any value. * Instead, it sets global name and password variables. * * <p> Also note that this method will set the username and password * values in the shared state in case subsequent LoginModules * want to use them via use/tryFirstPass. * * <p> * * @param getPasswdFromSharedState boolean that tells this method whether * to retrieve the password from the sharedState. */ private void getUsernamePassword(boolean getPasswdFromSharedState) throws LoginException { if (getPasswdFromSharedState) { // use the password saved by the first module in the stack username = (String)sharedState.get(NAME); password = (char[])sharedState.get(PWD); return; } // prompt for a username and password if (callbackHandler == null) throw new LoginException("Error: no CallbackHandler available " + "to garner authentication information from the user"); String protocol = userProvider.substring(0, userProvider.indexOf(":")); Callback[] callbacks = new Callback[2]; callbacks[0] = new NameCallback(protocol + " " + rb.getString("username: ")); callbacks[1] = new PasswordCallback(protocol + " " + rb.getString("password: "), false); try { callbackHandler.handle(callbacks); username = ((NameCallback)callbacks[0]).getName(); char[] tmpPassword = ((PasswordCallback)callbacks[1]).getPassword(); password = new char[tmpPassword.length]; System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length); ((PasswordCallback)callbacks[1]).clearPassword(); } catch (java.io.IOException ioe) { throw new LoginException(ioe.toString()); } catch (UnsupportedCallbackException uce) { throw new LoginException("Error: " + uce.getCallback().toString() + " not available to garner authentication information " + "from the user"); } // print debugging information if (strongDebug) { System.out.println("\t\t[JndiLoginModule] " + "user entered username: " + username); System.out.print("\t\t[JndiLoginModule] " + "user entered password: "); for (int i = 0; i < password.length; i++) System.out.print(password[i]); System.out.println(); } } /** * Verify a password against the encrypted passwd from /etc/shadow */ private boolean verifyPassword(String encryptedPassword, String password) { if (encryptedPassword == null) return false; Crypt c = new Crypt(); try { byte oldCrypt[] = encryptedPassword.getBytes("UTF8"); byte newCrypt[] = c.crypt(password.getBytes("UTF8"), oldCrypt); if (newCrypt.length != oldCrypt.length) return false; for (int i = 0; i < newCrypt.length; i++) { if (oldCrypt[i] != newCrypt[i]) return false; } } catch (java.io.UnsupportedEncodingException uee) { // cannot happen, but return false just to be safe return false; } return true; } /** * Clean out state because of a failed authentication attempt */ private void cleanState() { username = null; if (password != null) { for (int i = 0; i < password.length; i++) password[i] = ' '; password = null; } ctx = null; if (clearPass) { sharedState.remove(NAME); sharedState.remove(PWD); } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?