markt 2003/12/24 12:40:50 Modified: catalina/src/share/org/apache/catalina/authenticator AuthenticatorBase.java BasicAuthenticator.java DigestAuthenticator.java FormAuthenticator.java NonLoginAuthenticator.java SSLAuthenticator.java SingleSignOn.java webapps/tomcat-docs/config valve.xml Log: - Port of patch from TC5. - Fix bugs 4350, 9077, 10040 and 23881. - SSO in embedded Tomcat. - Patch provided by Brian Stansberry. Revision Changes Path 1.39 +87 -24 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/AuthenticatorBase.java Index: AuthenticatorBase.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/AuthenticatorBase.java,v retrieving revision 1.38 retrieving revision 1.39 diff -u -r1.38 -r1.39 --- AuthenticatorBase.java 18 Jul 2003 04:39:31 -0000 1.38 +++ AuthenticatorBase.java 24 Dec 2003 20:40:50 -0000 1.39 @@ -84,7 +84,6 @@ import org.apache.catalina.HttpRequest; import org.apache.catalina.HttpResponse; import org.apache.catalina.Lifecycle; -import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleException; import org.apache.catalina.LifecycleListener; import org.apache.catalina.Logger; @@ -99,7 +98,6 @@ import org.apache.catalina.deploy.LoginConfig; import org.apache.catalina.deploy.SecurityConstraint; import org.apache.catalina.util.LifecycleSupport; -import org.apache.catalina.util.RequestUtil; import org.apache.catalina.util.StringManager; import org.apache.catalina.valves.ValveBase; @@ -666,7 +664,7 @@ * * @param request Request we are processing * @param response Response we are creating - * @param login Login configuration describing how authentication + * @param config Login configuration describing how authentication * should be performed * * @exception IOException if an input/output error occurs @@ -817,7 +815,6 @@ protected synchronized String generateSessionId() { // Generate a byte array containing a session identifier - Random random = getRandom(); byte bytes[] = new byte[SESSION_ID_BYTES]; getRandom().nextBytes(bytes); bytes = getDigest().digest(bytes); @@ -975,6 +972,52 @@ /** + * Attempts reauthentication to the <code>Realm</code> using + * the credentials included in argument <code>entry</code>. + * + * @param ssoId identifier of SingleSignOn session with which the + * caller is associated + * @param request the request that needs to be authenticated + */ + protected boolean reauthenticateFromSSO(String ssoId, HttpRequest request) { + + if (sso == null || ssoId == null) + return false; + + boolean reauthenticated = false; + + SingleSignOnEntry entry = sso.lookup(ssoId); + if (entry != null && entry.getCanReauthenticate()) { + Principal reauthPrincipal = null; + Container parent = getContainer(); + if (parent != null) { + Realm realm = getContainer().getRealm(); + String username = entry.getUsername(); + if (realm != null && username != null) { + reauthPrincipal = + realm.authenticate(username, entry.getPassword()); + } + } + + if (reauthPrincipal != null) { + associate(ssoId, getSession(request, true)); + request.setAuthType(entry.getAuthType()); + request.setUserPrincipal(reauthPrincipal); + + reauthenticated = true; + if (debug >= 1) { + log(" Reauthenticated cached principal '" + + entry.getPrincipal().getName() + "' with auth type '" + + entry.getAuthType() + "'"); + } + } + } + + return reauthenticated; + } + + + /** * Register an authenticated Principal and authentication type in our * request, in the current session (if there is one), and with our * SingleSignOn valve, if there is one. Set the appropriate cookie @@ -998,10 +1041,10 @@ // Cache the authentication information in our request request.setAuthType(authType); request.setUserPrincipal(principal); - + + Session session = getSession(request, false); // Cache the authentication information in our session, if any - if (cache) { - Session session = getSession(request, false); + if (cache) { if (session != null) { session.setAuthType(authType); session.setPrincipal(principal); @@ -1019,19 +1062,39 @@ // Construct a cookie to be returned to the client if (sso == null) return; - HttpServletRequest hreq = - (HttpServletRequest) request.getRequest(); - HttpServletResponse hres = - (HttpServletResponse) response.getResponse(); - String value = generateSessionId(); - Cookie cookie = new Cookie(Constants.SINGLE_SIGN_ON_COOKIE, value); - cookie.setMaxAge(-1); - cookie.setPath("/"); - hres.addCookie(cookie); - - // Register this principal with our SSO valve - sso.register(value, principal, authType, username, password); - request.setNote(Constants.REQ_SSOID_NOTE, value); + + // Only create a new SSO entry if the SSO did not already set a note + // for an existing entry (as it would do with subsequent requests + // for DIGEST and SSL authenticated contexts) + String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE); + if (ssoId == null) { + // Construct a cookie to be returned to the client + HttpServletResponse hres = + (HttpServletResponse) response.getResponse(); + ssoId = generateSessionId(); + Cookie cookie = new Cookie(Constants.SINGLE_SIGN_ON_COOKIE, ssoId); + cookie.setMaxAge(-1); + cookie.setPath("/"); + hres.addCookie(cookie); + + // Register this principal with our SSO valve + sso.register(ssoId, principal, authType, username, password); + request.setNote(Constants.REQ_SSOID_NOTE, ssoId); + + } else { + // Update the SSO session with the latest authentication data + sso.update(ssoId, principal, authType, username, password); + } + + // Fix for Bug 10040 + // Always associate a session with a new SSO reqistration. + // SSO entries are only removed from the SSO registry map when + // associated sessions are destroyed; if a new SSO entry is created + // above for this request and the user never revisits the context, the + // SSO entry will never be cleared if we don't associate the session + if (session == null) + session = getSession(request, true); + sso.associate(ssoId, session); } 1.13 +23 -5 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/BasicAuthenticator.java Index: BasicAuthenticator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/BasicAuthenticator.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- BasicAuthenticator.java 23 Mar 2002 17:52:16 -0000 1.12 +++ BasicAuthenticator.java 24 Dec 2003 20:40:50 -0000 1.13 @@ -131,7 +131,7 @@ * * @param request Request we are processing * @param response Response we are creating - * @param login Login configuration describing how authentication + * @param config Login configuration describing how authentication * should be performed * * @exception IOException if an input/output error occurs @@ -144,10 +144,28 @@ // Have we already authenticated someone? Principal principal = ((HttpServletRequest) request.getRequest()).getUserPrincipal(); + String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE); if (principal != null) { if (debug >= 1) log("Already authenticated '" + principal.getName() + "'"); + // Associate the session with any existing SSO session + if (ssoId != null) + associate(ssoId, getSession(request, true)); return (true); + } + + // Is there an SSO session against which we can try to reauthenticate? + if (ssoId != null) { + if (debug >= 1) + log("SSO Id " + ssoId + " set; attempting reauthentication"); + /* Try to reauthenticate using data cached by SSO. If this fails, + either the original SSO logon was of DIGEST or SSL (which + we can't reauthenticate ourselves because there is no + cached username and password), or the realm denied + the user's reauthentication for some reason. + In either case we have to prompt the user for a logon */ + if (reauthenticateFromSSO(ssoId, request)) + return true; } // Validate any credentials already included with this request 1.12 +41 -12 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/DigestAuthenticator.java Index: DigestAuthenticator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/DigestAuthenticator.java,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- DigestAuthenticator.java 24 Mar 2003 23:19:19 -0000 1.11 +++ DigestAuthenticator.java 24 Dec 2003 20:40:50 -0000 1.12 @@ -76,7 +76,6 @@ import org.apache.catalina.HttpRequest; import org.apache.catalina.HttpResponse; import org.apache.catalina.Realm; -import org.apache.catalina.Session; import org.apache.catalina.deploy.LoginConfig; import org.apache.catalina.util.MD5Encoder; @@ -205,7 +204,7 @@ * * @param request Request we are processing * @param response Response we are creating - * @param login Login configuration describing how authentication + * @param config Login configuration describing how authentication * should be performed * * @exception IOException if an input/output error occurs @@ -218,8 +217,41 @@ // Have we already authenticated someone? Principal principal = ((HttpServletRequest) request.getRequest()).getUserPrincipal(); - if (principal != null) + //String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE); + if (principal != null) { + if (debug >= 1) + log("Already authenticated '" + principal.getName() + "'"); + // Associate the session with any existing SSO session in order + // to get coordinated session invalidation at logout + String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE); + if (ssoId != null) + associate(ssoId, getSession(request, true)); return (true); + } + + // NOTE: We don't try to reauthenticate using any existing SSO session, + // because that will only work if the original authentication was + // BASIC or FORM, which are less secure than the DIGEST auth-type + // specified for this webapp + // + // Uncomment below to allow previous FORM or BASIC authentications + // to authenticate users for this webapp + // TODO make this a configurable attribute (in SingleSignOn??) + /* + // Is there an SSO session against which we can try to reauthenticate? + if (ssoId != null) { + if (debug >= 1) + log("SSO Id " + ssoId + " set; attempting reauthentication"); + // Try to reauthenticate using data cached by SSO. If this fails, + // either the original SSO logon was of DIGEST or SSL (which + // we can't reauthenticate ourselves because there is no + // cached username and password), or the realm denied + // the user's reauthentication for some reason. + // In either case we get logon credentials from the user. + if (reauthenticateFromSSO(ssoId, request)) + return true; + } + */ // Validate any credentials already included with this request HttpServletRequest hreq = @@ -263,8 +295,6 @@ * * @param request HTTP servlet request * @param authorization Authorization credentials from this request - * @param login Login configuration describing how authentication - * should be performed * @param realm Realm used to authenticate Principals */ protected static Principal findPrincipal(HttpServletRequest request, @@ -291,7 +321,6 @@ String qop = null; String uri = null; String response = null; - String opaque = null; String method = request.getMethod(); while (commaTokenizer.hasMoreTokens()) { @@ -442,8 +471,8 @@ * </pre> * * @param request HTTP Servlet request - * @param resonse HTTP Servlet response - * @param login Login configuration describing how authentication + * @param response HTTP Servlet response + * @param config Login configuration describing how authentication * should be performed * @param nOnce nonce token */ 1.21 +22 -11 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/FormAuthenticator.java Index: FormAuthenticator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/FormAuthenticator.java,v retrieving revision 1.20 retrieving revision 1.21 diff -u -r1.20 -r1.21 --- FormAuthenticator.java 14 Mar 2002 20:58:24 -0000 1.20 +++ FormAuthenticator.java 24 Dec 2003 20:40:50 -0000 1.21 @@ -74,7 +74,6 @@ import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import org.apache.catalina.HttpRequest; import org.apache.catalina.HttpResponse; import org.apache.catalina.Realm; @@ -129,7 +128,7 @@ * * @param request Request we are processing * @param response Response we are creating - * @param login Login configuration describing how authentication + * @param config Login configuration describing how authentication * should be performed * * @exception IOException if an input/output error occurs @@ -148,16 +147,31 @@ // Have we already authenticated someone? Principal principal = hreq.getUserPrincipal(); + String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE); if (principal != null) { if (debug >= 1) log("Already authenticated '" + principal.getName() + "'"); - String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE); + // Associate the session with any existing SSO session if (ssoId != null) associate(ssoId, getSession(request, true)); return (true); } + // Is there an SSO session against which we can try to reauthenticate? + if (ssoId != null) { + if (debug >= 1) + log("SSO Id " + ssoId + " set; attempting reauthentication"); + // Try to reauthenticate using data cached by SSO. If this fails, + // either the original SSO logon was of DIGEST or SSL (which + // we can't reauthenticate ourselves because there is no + // cached username and password), or the realm denied + // the user's reauthentication for some reason. + // In either case we have to prompt the user for a logon */ + if (reauthenticateFromSSO(ssoId, request)) + return true; + } + // Have we authenticated this user before but have caching disabled? if (!cache) { session = getSession(request, true); @@ -195,9 +209,6 @@ register(request, response, principal, Constants.FORM_METHOD, (String) session.getNote(Constants.SESS_USERNAME_NOTE), (String) session.getNote(Constants.SESS_PASSWORD_NOTE)); - String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE); - if (ssoId != null) - associate(ssoId, session); if (restoreRequest(request, session)) { if (debug >= 1) log("Proceed to restored request"); @@ -377,7 +388,7 @@ while (paramNames.hasNext()) { String paramName = (String) paramNames.next(); String paramValues[] = - (String[]) saved.getParameterValues(paramName); + saved.getParameterValues(paramName); request.addParameter(paramName, paramValues); } } 1.4 +15 -10 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/NonLoginAuthenticator.java Index: NonLoginAuthenticator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/NonLoginAuthenticator.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- NonLoginAuthenticator.java 22 Jul 2001 20:09:19 -0000 1.3 +++ NonLoginAuthenticator.java 24 Dec 2003 20:40:50 -0000 1.4 @@ -66,13 +66,9 @@ import java.io.IOException; -import java.security.Principal; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; + import org.apache.catalina.HttpRequest; import org.apache.catalina.HttpResponse; -import org.apache.catalina.Realm; -import org.apache.catalina.Session; import org.apache.catalina.deploy.LoginConfig; @@ -123,7 +119,7 @@ * * @param request Request we are processing * @param response Response we are creating - * @param login Login configuration describing how authentication + * @param config Login configuration describing how authentication * should be performed * * @exception IOException if an input/output error occurs @@ -132,6 +128,15 @@ HttpResponse response, LoginConfig config) throws IOException { + + /* Associating this request's session with an SSO would allow + coordinated session invalidation, but should the session for + a webapp that the user didn't log into be invalidated when + another session is logged out? + String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE); + if (ssoId != null) + associate(ssoId, getSession(request, true)); + */ if (debug >= 1) log("User authentication is not required"); 1.14 +35 -8 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/SSLAuthenticator.java Index: SSLAuthenticator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/SSLAuthenticator.java,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- SSLAuthenticator.java 23 Sep 2002 00:25:10 -0000 1.13 +++ SSLAuthenticator.java 24 Dec 2003 20:40:50 -0000 1.14 @@ -73,10 +73,7 @@ import org.apache.catalina.Globals; import org.apache.catalina.HttpRequest; import org.apache.catalina.HttpResponse; -import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleException; -import org.apache.catalina.Realm; -import org.apache.catalina.Session; import org.apache.catalina.deploy.LoginConfig; @@ -124,7 +121,7 @@ * * @param request Request we are processing * @param response Response we are creating - * @param login Login configuration describing how authentication + * @param config Login configuration describing how authentication * should be performed * * @exception IOException if an input/output error occurs @@ -137,11 +134,41 @@ // Have we already authenticated someone? Principal principal = ((HttpServletRequest) request.getRequest()).getUserPrincipal(); + //String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE); if (principal != null) { if (debug >= 1) log("Already authenticated '" + principal.getName() + "'"); + // Associate the session with any existing SSO session in order + // to get coordinated session invalidation at logout + String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE); + if (ssoId != null) + associate(ssoId, getSession(request, true)); return (true); } + + // NOTE: We don't try to reauthenticate using any existing SSO session, + // because that will only work if the original authentication was + // BASIC or FORM, which are less secure than the CLIENT-CERT auth-type + // specified for this webapp + // + // Uncomment below to allow previous FORM or BASIC authentications + // to authenticate users for this webapp + // TODO make this a configurable attribute (in SingleSignOn??) + /* + // Is there an SSO session against which we can try to reauthenticate? + if (ssoId != null) { + if (debug >= 1) + log("SSO Id " + ssoId + " set; attempting reauthentication"); + // Try to reauthenticate using data cached by SSO. If this fails, + // either the original SSO logon was of DIGEST or SSL (which + // we can't reauthenticate ourselves because there is no + // cached username and password), or the realm denied + // the user's reauthentication for some reason. + // In either case we have to prompt the user for a logon + if (reauthenticateFromSSO(ssoId, request)) + return true; + } + */ // Retrieve the certificate chain for this client HttpServletResponse hres = 1.13 +179 -57 jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/SingleSignOn.java Index: SingleSignOn.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/SingleSignOn.java,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- SingleSignOn.java 23 Dec 2003 17:55:39 -0000 1.12 +++ SingleSignOn.java 24 Dec 2003 20:40:50 -0000 1.13 @@ -145,6 +145,14 @@ */ protected LifecycleSupport lifecycle = new LifecycleSupport(this); + + /** + * Indicates whether this valve should require a downstream Authenticator to + * reauthenticate each request, or if it itself can bind a UserPrincipal + * and AuthType object to the request. + */ + private boolean requireReauthentication = false; + /** * The cache of single sign on identifiers, keyed by the Session that is @@ -191,6 +199,75 @@ } + /** + * Gets whether each request needs to be reauthenticated (by an + * Authenticator downstream in the pipeline) to the security + * <code>Realm</code>, or if this Valve can itself bind security info + * to the request based on the presence of a valid SSO entry without + * rechecking with the <code>Realm</code.. + * + * @return <code>true</code> if it is required that a downstream + * Authenticator reauthenticate each request before calls to + * <code>HttpServletRequest.setUserPrincipal()</code> + * and <code>HttpServletRequest.setAuthType()</code> are made; + * <code>false</code> if the <code>Valve</code> can itself make + * those calls relying on the presence of a valid SingleSignOn + * entry associated with the request. + * + * @see #setRequireReauthentication + */ + public boolean getRequireReauthentication() + { + return requireReauthentication; + } + + + /** + * Sets whether each request needs to be reauthenticated (by an + * Authenticator downstream in the pipeline) to the security + * <code>Realm</code>, or if this Valve can itself bind security info + * to the request, based on the presence of a valid SSO entry, without + * rechecking with the <code>Realm</code. + * <p> + * If this property is <code>false</code> (the default), this + * <code>Valve</code> will bind a UserPrincipal and AuthType to the request + * if a valid SSO entry is associated with the request. It will not notify + * the security <code>Realm</code> of the incoming request. + * <p> + * This property should be set to <code>true</code> if the overall server + * configuration requires that the <code>Realm</code> reauthenticate each + * request thread. An example of such a configuration would be one where + * the <code>Realm</code> implementation provides security for both a + * web tier and an associated EJB tier, and needs to set security + * credentials on each request thread in order to support EJB access. + * <p> + * If this property is set to <code>true</code>, this Valve will set flags + * on the request notifying the downstream Authenticator that the request + * is associated with an SSO session. The Authenticator will then call its + * [EMAIL PROTECTED] AuthenticatorBase#reauthenticateFromSSO reauthenticateFromSSO} + * method to attempt to reauthenticate the request to the + * <code>Realm</code>, using any credentials that were cached with this + * Valve. + * <p> + * The default value of this property is <code>false</code>, in order + * to maintain backward compatibility with previous versions of Tomcat. + * + * @param required <code>true</code> if it is required that a downstream + * Authenticator reauthenticate each request before calls + * to <code>HttpServletRequest.setUserPrincipal()</code> + * and <code>HttpServletRequest.setAuthType()</code> are + * made; <code>false</code> if the <code>Valve</code> can + * itself make those calls relying on the presence of a + * valid SingleSignOn entry associated with the request. + * + * @see AuthenticatorBase#reauthenticateFromSSO + */ + public void setRequireReauthentication(boolean required) + { + this.requireReauthentication = required; + } + + // ------------------------------------------------------ Lifecycle Methods @@ -299,9 +376,23 @@ } if (ssoId == null) return; + - // Deregister this single session id, invalidating associated sessions - deregister(ssoId); + /* + * Was the session destroyed as the result of a timeout? + * If so, we'll just remove the expired session from the + * SSO. If the session was logged out, we'll log out + * of all session associated with the SSO. + */ + if (System.currentTimeMillis() - session.getLastAccessedTime() >= + session.getMaxInactiveInterval() * 1000) { + removeSession(ssoId, session); + } + else { + // The session was logged out. + // Deregister this single session id, invalidating associated sessions + deregister(ssoId); + } } @@ -384,11 +475,14 @@ if (entry != null) { if (debug >= 1) log(" Found cached principal '" + - entry.principal.getName() + "' with auth type '" + - entry.authType + "'"); + entry.getPrincipal().getName() + "' with auth type '" + + entry.getAuthType() + "'"); request.setNote(Constants.REQ_SSOID_NOTE, cookie.getValue()); - ((HttpRequest) request).setAuthType(entry.authType); - ((HttpRequest) request).setUserPrincipal(entry.principal); + // Only set security elements if reauthentication is not required + if (!getRequireReauthentication()) { + ((HttpRequest) request).setAuthType(entry.getAuthType()); + ((HttpRequest) request).setUserPrincipal(entry.getPrincipal()); + } } else { if (debug >= 1) log(" No cached principal found, erasing SSO cookie"); @@ -510,6 +604,81 @@ } + + /** + * Remove a single Session from a SingleSignOn. Called when + * a session is timed out and no longer active. + * + * @param ssoId Single sign on identifier from which to remove the session. + * @param session the session to be removed. + */ + void removeSession(String ssoId, Session session) { + + if (debug >= 1) + log("Removing session " + session.toString() + " from sso id " + + ssoId ); + + // Get a reference to the SingleSignOn + SingleSignOnEntry entry = lookup(ssoId); + if (entry == null) + return; + + // Remove the inactive session from SingleSignOnEntry + entry.removeSession(session); + + // Remove the inactive session from the 'reverse' Map. + synchronized(reverse) { + reverse.remove(session); + } + + // If there are not sessions left in the SingleSignOnEntry, + // deregister the entry. + if (entry.findSessions().length == 0) { + deregister(ssoId); + } + } + + + /** + * Updates any <code>SingleSignOnEntry</code> found under key + * <code>ssoId</code> with the given authentication data. + * <p> + * The purpose of this method is to allow an SSO entry that was + * established without a username/password combination (i.e. established + * following DIGEST or CLIENT-CERT authentication) to be updated with + * a username and password if one becomes available through a subsequent + * BASIC or FORM authentication. The SSO entry will then be usable for + * reauthentication. + * <p> + * <b>NOTE:</b> Only updates the SSO entry if a call to + * <code>SingleSignOnEntry.getCanReauthenticate()</code> returns + * <code>false</code>; otherwise, it is assumed that the SSO entry already + * has sufficient information to allow reauthentication and that no update + * is needed. + * + * @param ssoId identifier of Single sign to be updated + * @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 + */ + void update(String ssoId, Principal principal, String authType, + String username, String password) { + + SingleSignOnEntry sso = lookup(ssoId); + if (sso != null && !sso.getCanReauthenticate()) { + if (debug >= 1) + log("Update sso id " + ssoId + " to auth type " + authType); + + synchronized(sso) { + sso.updateCredentials(principal, authType, username, password); + } + + } + } + // ------------------------------------------------------ Protected Methods @@ -561,53 +730,6 @@ return ((SingleSignOnEntry) cache.get(ssoId)); } - } - - -} - - -// ------------------------------------------------------------ Private Classes - - -/** - * A private class representing entries in the cache of authenticated users. - */ -class SingleSignOnEntry { - - public String authType = null; - - public String password = null; - - public Principal principal = null; - - public Session sessions[] = new Session[0]; - - public String username = null; - - public SingleSignOnEntry(Principal principal, String authType, - String username, String password) { - super(); - this.principal = principal; - this.authType = authType; - this.username = username; - this.password = password; - } - - public synchronized void addSession(SingleSignOn sso, Session session) { - for (int i = 0; i < sessions.length; i++) { - if (session == sessions[i]) - return; - } - Session results[] = new Session[sessions.length + 1]; - System.arraycopy(sessions, 0, results, 0, sessions.length); - results[sessions.length] = session; - sessions = results; - session.addSessionListener(sso); - } - - public synchronized Session[] findSessions() { - return (this.sessions); } } 1.9 +10 -0 jakarta-tomcat-4.0/webapps/tomcat-docs/config/valve.xml Index: valve.xml =================================================================== RCS file: /home/cvs/jakarta-tomcat-4.0/webapps/tomcat-docs/config/valve.xml,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- valve.xml 12 Jan 2003 17:26:48 -0000 1.8 +++ valve.xml 24 Dec 2003 20:40:50 -0000 1.9 @@ -309,6 +309,16 @@ <p>Detail level of debugging messages created by this component. By default, this is set to zero (0), which means no debug output.</p> </attribute> + + <attribute name="requireReauthentication" required="false"> + <p>Default false. Flag to determine whether each request needs to be + reauthenticated to the security <strong>Realm</strong>. If "true", this + Valve uses cached security credentials (username and password) to + reauthenticate to the <strong>Realm</strong> each request associated + with an SSO session. If "false", the Valve can itself authenticate + requests based on the presence of a valid SSO cookie, without + rechecking with the <strong>Realm</strong>.</p> + </attribute> </attributes>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]