This patch causes logout() and invalidate() to do the Servlet spec 2.4
"right thing."  I implemented it using the Data field of SessionEvent to
distinguish between logout/invalidate.

Can someone apply this?  THANKS.

Cheers,
-bob

On Sat, 2002-08-10 at 23:02, Bob Herrmann wrote:
> The servlet 2.4 spec adds a new method, "HttpSession.logout()";
> 
> How do we implement this?
> 
> For the non-single signon case, "logout()" is identical to
> "invalidate()"
> 
> For single signon, Tomcat currently uses a "single signon valve" which
> listens for "Session Destroy" events.  When a "Session Destroy" happens,
> all sessions are removed.  A "Session Destroy" happens now when either
> invalidate() or logout() happens.  For logout, everything is fine, for
> invalidate() - only the session for the current web app should be
> removed.
> 
> So, when a session logout() or invalidate() is called, what should
> happen?  A "Session Destroy" with extra data indicating a logout or
> invalidate occured?  Or should a new session event be created to
> indicate a "logout" is happening?
> 
> comments/ideas?
> 
> Cheers,
> -bob
> 
> 
> 
> 
> 
> -- 
> Cheers,
> -bob
> 
> 
> --
> To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Index: authenticator/SingleSignOn.java
===================================================================
RCS file: /home/cvspublic/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/authenticator/SingleSignOn.java,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 SingleSignOn.java
--- authenticator/SingleSignOn.java	18 Jul 2002 16:48:03 -0000	1.1.1.1
+++ authenticator/SingleSignOn.java	12 Aug 2002 18:34:52 -0000
@@ -293,6 +293,7 @@
         Session session = event.getSession();
         if (debug >= 1)
             log("Process session destroyed on " + session);
+
         String ssoId = null;
         synchronized (reverse) {
             ssoId = (String) reverse.get(session);
@@ -300,8 +301,22 @@
         if (ssoId == null)
             return;
 
-        // Deregister this single session id, invalidating associated sessions
-        deregister(ssoId);
+        if ( event.getData() != null 
+             && "logout".equals( event.getData().toString() )) {
+
+            log("XXXXX logout event on " + ssoId);
+
+            // logout of all applications
+            deregister(ssoId);
+
+        } else {
+
+            log("XXXXX invalidate of just one session " + ssoId + " " + session);
+
+            // invalidate just one session
+            deregister(ssoId, session);
+
+        }
 
     }
 
@@ -442,6 +457,35 @@
 
     }
 
+    /**
+     * Deregister the specified session.  If it is the last session,
+     * then also get rid of the single sign on identifier
+     *
+     * @param ssoId Single sign on identifier
+     * @param session Session to be deregistered
+     */
+    private void deregister(String ssoId, Session session) {
+
+        synchronized (reverse) {
+            reverse.remove(session);
+        }
+
+        SingleSignOnEntry sso = lookup(ssoId);
+        if ( sso == null )
+            return;
+
+        sso.removeSession( session );
+
+        // see if we are the last session, if so blow away ssoId
+        Session sessions[] = sso.findSessions();
+        if ( sessions == null || sessions.length == 0 ) {
+            synchronized (cache) {
+                sso = (SingleSignOnEntry) cache.remove(ssoId);
+            }
+        }
+
+    }
+
 
     /**
      * Deregister the specified single sign on identifier, and invalidate
@@ -449,7 +493,7 @@
      *
      * @param ssoId Single sign on identifier to deregister
      */
-    void deregister(String ssoId) {
+    private void deregister(String ssoId) {
 
         if (debug >= 1)
             log("Deregistering sso id '" + ssoId + "'");
@@ -459,6 +503,7 @@
         synchronized (cache) {
             sso = (SingleSignOnEntry) cache.remove(ssoId);
         }
+
         if (sso == null)
             return;
 
@@ -601,6 +646,16 @@
         results[sessions.length] = session;
         sessions = results;
         session.addSessionListener(sso);
+    }
+
+    public synchronized void removeSession(Session session) {
+        Session[] nsessions = new Session[sessions.length - 1];
+        for (int i = 0, j = 0; i < sessions.length; i++) {
+            if (session == sessions[i])
+                continue;
+            nsessions[j++] = sessions[i];
+        }
+        sessions = nsessions;
     }
 
     public synchronized Session[] findSessions() {
Index: session/StandardSession.java
===================================================================
RCS file: /home/cvspublic/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/session/StandardSession.java,v
retrieving revision 1.3
diff -u -r1.3 StandardSession.java
--- session/StandardSession.java	8 Aug 2002 04:03:44 -0000	1.3
+++ session/StandardSession.java	12 Aug 2002 18:34:56 -0000
@@ -1066,7 +1066,10 @@
             throw new IllegalStateException
                 (sm.getString("standardSession.isNew.ise"));
 
-        invalidate();
+
+        // kills all sessions
+        fireSessionEvent(Session.SESSION_DESTROYED_EVENT, "logout");
+
     }
 
 

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to