5 Replies Latest reply on Jan 26, 2010 5:36 PM by jkaipa

    Invalidating an HttpSession in Seam

    jgreene

      Hi -
      Our app uses Seam, and I'm trying to invalidate an active session.  I store a reference to each active session in a HashMap by username.  I've tried to follow Gavin's guidance and am not calling invalidate directly.  Here's the code I'm using to try to do this:


      String key = account.getUsername();
      if(activeSessions.contains(key))
      {
         HttpSession oldSession =  activeSessions.getSessionForUser(key);
                              
      try
      {
         if(oldSession != null)
         {
            Identity oldIdentity = (Identity)oldSession.getAttribute("org.jboss.seam.security.identity");
      
            oldIdentity.logout();
         }
      }
      catch(IllegalStateException ise) {}
                              
      activeSessions.removeUserSession(key);
      
      }




      During debug, I see that the HttpSession has the org.jboss.seam.security.identity attribute, and when I call logout on it, the session that is currently in context, rather than the one associated with the session object I just pulled from the HashMap, is invalidated.  I'm not a Seam guru, but I certainly thought that getting the identity object from the session in the list would be the right thing to do.  I'm obviously doing something wrong, and what it seems to come down to is that I need to know how to  get the right Identity object from the HttpSession I'm storing so I can call logout on it.


      Thanks for any ideas or advice.

        • 1. Re: Invalidating an HttpSession in Seam
          btonez

          Hi Joe,


          You're correct to use Identity.logout() to invalidate the session, but you're doing way too much work to get the Identity.  Seam already stores the HttpSession and its variables, and all you need to do to get the current Identity is either inject it using the @In annotation, or call Identity.instance().


          So all that code can be replaced by Identity.instance().logout() 


          Most classes in Seam have a static instance() method, or you can call any of the Component.getInstance(...) methods passing in the class name to look it up in all the contexts without needing to explicitly cache them.


          Hope this helps,


          Brenton

          • 2. Re: Invalidating an HttpSession in Seam
            jgreene

            Brenton -
            Wow, thanks for the quick response!


            I think I may not have provided enough info, so let me add a little more.  I do indeed inject the Identity component into my LoginManagerBean in order to use a little Seam security when logging a user into the app.  My issue is that I have to satisfy a requirement to prevent a single user from having more than one active session at a time.  So when a user logs in, I store a reference to his HttpSession in a HashMap with the username as the key.  So if the user, say, opens another browser, or tries to log in from another machine, the code sees that this user already has an active session (by comparing username).  I present a new page to the user telling him this, and if he chooses, he can continue logging in but that his previous session will be trashed.  If this happens, what I need to do is find the user's HttpSession record in the HashMap, invalidate it, remove it, then add the current HttpSession as a replacement.


            By the way, I wrote a SessionTimeoutNotifier class that implements HttpSessionBindingListener so that I can log the invalidation time to a db table, because in these cases where the user makes a conscious decision to remove a session, I need to record when this happened.


            So you see, the Identity I'm trying to get to is not the current one as I see it, but the one associated with the user's previous session/login, and is associated with the session i'm trying to invalidate.


            I think this describes more accurately what I'm struggling with, and I hope I'm still wrong and that what I want to do is easy.


            Thanks again for any help.

            • 3. Re: Invalidating an HttpSession in Seam
              jgreene

              Hi Brenton -
              I've tried a couple of other things to help me kill the session I need to kill.  I went back to the old way of calling invalidate() on the particular HttpSession object i pull out of my HashMap, even though Gavin says this is illegal.  On the surface, this seems to accomplish what I want, although at what cost i don't yet know.  Calling invalidate on the HttpSession certainly submarines the Seam session, and renders that browser session useless, but what happens to all the Seam-related stuff left in that session.  Can I assume it will be safely and reliably garbage collected?


              The only apparent problem for me with this approach is that my SessionTimeoutNotifier does not get alerted so that the valueUnbound method gets called - I don't know why.  so the invalidation time does not get written to the db.  I can get around this I think, though.


              anyway, I just thought I'd share my experiences with this in case someone else has a similar problem and maybe even a slick solution to properly invalidating sessions in Seam.


              Thanks.

              • 4. Re: Invalidating an HttpSession in Seam
                marcinderylo

                Hi, sorry for resurrecting an old thread but we've got the same problem as Joe and couldn't find any way to invalidate other user's session other than calling invalidate() on the session itself. The problem with Identity.logout() is that it doesn't invalide the session the Identity instance is associated with - it only unauthenticates it and the session that gets invalidated is the one from which you call the logout method.
                Indeed, a HttpSessionListener shows clearly that only one session gets invalidated, the one from which we try to force logout. The other session's user is logged out but his session is not invalidated.


                What Identity.logout() does to invalidate the session is:



                Session.instance().invalidate();




                and it's pretty obvious why the problem happens.


                Currently we are just invalidating the session and ignoring Seam complaints about not terminating the session in a proper way. Can anyone suggest a better workaround? Or maybe I should fill a JIRA for that issue (I'm not sure, the logout method does not have any comments on it so can't say whether it's working to its contract or not )?


                Thanks,
                Marcin

                • 5. Re: Invalidating an HttpSession in Seam
                  jkaipa

                  Hello Joe/Marcin, Have you found a solution for this issue? I am also sailing in the same boat and exploring possibilities.


                  Thanks, Guru.