SingleSignOnEntry.java |
/* * JBoss, the OpenSource WebOS * * Distributable under LGPL license. * See terms of license at gnu.org. */ package org.jboss.web.tomcat.tc5.sso; import java.security.Principal; import org.apache.catalina.Session; import org.apache.catalina.authenticator.Constants; import org.apache.catalina.authenticator.SingleSignOn; /** * A class that represents entries in the cache of authenticated users. * * @author Brian E. Stansberry, based on work by Craig R. McClanahan * @version $Revision: 1.3 $ $Date: 2004/09/13 00:08:30 $ * @see SingleSignOn */ class SingleSignOnEntry { // ------------------------------------------------------ Instance Fields private String authType = null; private String password = null; private Principal principal = null; private Session sessions[] = new Session[0]; private String username = null; private boolean canReauthenticate = false; // --------------------------------------------------------- Constructors /** * Creates a new SingleSignOnEntry * * @param principal the <code>Principal</code> returned by the latest * call to <code>Realm.authenticate</code>. * @param authType the type of authenticator used (BASIC, CLIENT-CERT, * DIGEST or FORM) * @param username the username (if any) used for the authentication * @param password the password (if any) used for the authentication */ SingleSignOnEntry(Principal principal, String authType, String username, String password) { updateCredentials(principal, authType, username, password); } // ------------------------------------------------------- Package Methods /** * Adds a <code>Session</code> to the list of those associated with * this SSO. * * @param sso The <code>SingleSignOn</code> valve that is managing * the SSO session. * @param session The <code>Session</code> being associated with the SSO. * @return <code>true</code> if the given Session was a new addition (i.e. * was not previously associated with this entry); * <code>false</code> otherwise. */ synchronized boolean addSession(SingleSignOn sso, Session session) { for (int i = 0; i < sessions.length; i++) { if (session == sessions[i]) return false; } Session results[] = new Session[sessions.length + 1]; System.arraycopy(sessions, 0, results, 0, sessions.length); results[sessions.length] = session; sessions = results; session.addSessionListener(sso); return true; } /** * Removes the given <code>Session</code> from the list of those * associated with this SSO. * * @param session the <code>Session</code> to remove. * @return <code>true</code> if the given Session needed to be removed * (i.e. was in fact previously associated with this entry); * <code>false</code> otherwise. */ synchronized boolean removeSession(Session session) { if (sessions.length == 0) return false; boolean removed = false; Session[] nsessions = new Session[sessions.length - 1]; for (int i = 0, j = 0; i < sessions.length; i++) { if (session == sessions[i]) { removed = true; continue; } else if (!removed && i == nsessions.length) { // We have tested all our sessions, and have not had to // remove any; break loop now so we don't cause an // ArrayIndexOutOfBounds on nsessions break; } nsessions[j++] = sessions[i]; } sessions = nsessions; // Only if we removed a session, do we replace our session list if (removed) sessions = nsessions; return removed; } /** * Returns the <code>Session</code>s associated with this SSO. */ synchronized Session[] findSessions() { return (this.sessions); } /** * Gets the name of the authentication type originally used to authenticate * the user associated with the SSO. * * @return "BASIC", "CLIENT-CERT", "DIGEST", "FORM" or "NONE" */ String getAuthType() { return (this.authType); } /** * Gets whether the authentication type associated with the original * authentication supports reauthentication. * * @return <code>true</code> if <code>getAuthType</code> returns * "BASIC" or "FORM", <code>false</code> otherwise. */ boolean getCanReauthenticate() { return (this.canReauthenticate); } /** * Gets the password credential (if any) associated with the SSO. * * @return the password credential associated with the SSO, or * <code>null</code> if the original authentication type * does not involve a password. */ String getPassword() { return (this.password); } /** * Gets the <code>Principal</code> that has been authenticated by * the SSO. * <p/> * <b>NOTE: </b> May return <code>null</code> if this object was * retrieved via a lookup from another node in a cluster. Interface * <code>Principal</code> does not extend <code>Serializable</code>, * so a <code>SingleSignOnEntry</code>'s principal member cannot be * serialized as part of SSO management in a cluster. A * <code>Principal</code> cannot be bound to a * <code>SingleSignOnEntry</code> until the SSO has been authenticated * by the local node. * * @return The <code>Principal</code> that has been authenticated by * the local SSO, or <code>null</code> if no authentication * has been performed yet in this cluster node. */ Principal getPrincipal() { return (this.principal); } /** * Sets the <code>Principal</code> that has been authenticated by * the SSO. */ void setPrincipal(Principal principal) { this.principal = principal; } /** * Returns the number of sessions associated with this SSO, either * locally or remotely. */ int getSessionCount() { return (sessions.length); } /** * Gets the username provided by the user as part of the authentication * process. */ String getUsername() { return (this.username); } /** * Updates the SingleSignOnEntry to reflect the latest security * information associated with the caller. * * @param principal the <code>Principal</code> returned by the latest * call to <code>Realm.authenticate</code>. * @param authType the type of authenticator used (BASIC, CLIENT-CERT, * DIGEST or FORM) * @param username the username (if any) used for the authentication * @param password the password (if any) used for the authentication */ synchronized boolean updateCredentials(Principal principal, String authType, String username, String password) { boolean changed = (safeEquals(this.principal, principal) || safeEquals(this.authType, authType) || safeEquals(this.username, username) || safeEquals(this.password, password)); this.principal = principal; this.authType = authType; this.username = username; this.password = password; this.canReauthenticate = (Constants.BASIC_METHOD.equals(authType) || Constants.FORM_METHOD.equals(authType)); return changed; } // ------------------------------------------------------- Private Methods private boolean safeEquals(Object a, Object b) { return ((a == b) || (a != null && a.equals(b)) || (b != null && b.equals(a))); } }
SingleSignOnEntry.java |