10 Replies Latest reply on Mar 20, 2003 2:30 AM by milder60

    Remove Principal Object from Request

    milder60

      I'm using request.getUserPrincipal() to get a username for loading querying an ejb to load a light user object and storing in session or cache. The problem is that no matter how I store the object (cache, SFbean or session) I still need to call request.getUserPrincipal() to get the username of the logged in user.

      The Problem:
      I cannot remove the Principal object from the request when the user logs out. This causes the application to think the user is still logged in (and display things a logged out user shouldn't see) A call to request.getSesssion().invalidate() does not remove that Principal... therefore on a logout action here is what happens

      1. Click logout
      2. Logout Action -> request.getSession().invalidate()
      3. Forward to GoHomeAction.java
      4. In GoHomeAction the SessionManager calls .getUserObj()
      5. In SessionManager:
      if (null == request.getUserPrincipal()){
      return false;
      }
      6. SessionManager (after someone logs in and logs out) still finds a valid Principal in request, and loads the user obj for that user (who has logged out)

      So even though the user has logged out and the session is dead, somehow his Principal object is still kicking around, and the SessionManager finds that object and essentially recreates the users session object (even though the user is no longer logged in).

      Now I'm not even sure that .getUserPrincipal() is the 'right way' of doing this sort of thing, but it seems to make sense to me. The undying .getUserPrincipal() doesn't make any sense whatsoever (to me anyway).

      I'm using Jetty + JBoss3.0.0. I tried request.remove("org.mortbay...AuthUser"), but I got slapped by Jetty.

      Thanks for any help/insight

      Cheers
      Dave

        • 1. Re: Remove Principal Object from Request
          giurax

          Hi,
          you must be using BASIC authentication, in this case the only way to logout is obtained by closing the browser window(don't ask me why, I found it on Tomcat documentation),if you used FORM authentication you could just call session.invalidate() and life would immediately become much better;-D

          • 2. Re: Remove Principal Object from Request
            milder60

            No I'm acutally using FORM auth. With FORM auth if you call request.getSession().invalidate() it will appear that your Principal user is gone, but he's still kicking around somewhere. I'd love to user JAAS .logout() but nobody seems to be able to figure out how to explicitly call it!!!!

            • 3. Re: Remove Principal Object from Request

              Dave,

              To logout, Session.invalidate() is the way to go. The reason that it does not work in your case, is that you are testing whether the user is still logged in, in the _same_ http request (i suppose that step 3 is a server redirect). request.getUserPrincipal() still returns a principal, because the current request was made while the user was still logged in.
              A Jaas logout won't help for the same reason: the request is still (correctly) associated with the user that made it.

              I see two directions for a solution:
              - use a client redirect after the logout action; the next client request will be not logged in (as the session is gone)
              - record the fact that the user logged of in the current request, by setting an attribute (in the session, or in the request), and test for this in the SessionManager.

              Hth
              Peter

              • 4. Re: Remove Principal Object from Request
                milder60

                Ok here is what I do now.

                In logoutAction (struts action class)
                1. Call SessionManager.logout() which invalidates session
                and removes the users session object (should be redundant I know)
                2. redirect to a logoutServlet which AGAIN invalidates session (just to ensure I'm not crazy)
                3. response.sendRedirct( loggedout.html);
                4. Click a link back into the system and acutally finds the userobject again!!!

                Step #1 (logoutAction)
                sLog.debug("Attempting to log user out");
                String userName = request.getUserPrincipal().getName();
                request.getSession().removeAttribute(SessionConstants.HTTP_USER_LIGHT);
                request.getSession().invalidate();
                if (sLog.isDebugEnabled()){
                sLog.debug("attempting to see if session obj is really gone") ;
                sLog.debug("value="+request.getSession().getAttribute(SessionConstants.HTTP_USER_LIGHT));
                //the above will return null.. user obj is gone...for now
                }
                request.setAttribute("loggedOut", Boolean.TRUE);

                Steps #2 and #3 (logoutServlet)
                HttpServletRequest req = (HttpServletRequest)arg0;
                HttpServletResponse res = (HttpServletResponse)arg1;
                req.getSession().invalidate();
                res.sendRedirect("/pages/common/logout.html");


                In logout.html you can click link back to main url of system. There the code will check to see if a user is logged in... and guess what? The user is logged in. Code below:

                Step #4
                UserLight userLight = (UserLight)request.getSession().getAttribute(SessionConstants.HTTP_USER_LIGHT);
                if (userLight != null) {
                sLog.debug("Getting user session info from session");
                //user details are in session
                return userLight;
                } else {//do something }

                Am I insane or have I just missed something stupid?

                • 5. Re: Remove Principal Object from Request
                  milder60

                  Ok here is what I do now.

                  In logoutAction (struts action class)
                  1. Call SessionManager.logout() which invalidates session
                  and removes the users session object (should be redundant I know)
                  2. redirect to a logoutServlet which AGAIN invalidates session (just to ensure I'm not crazy)
                  3. response.sendRedirct( loggedout.html);
                  4. Click a link back into the system and acutally finds the userobject again!!!

                  Step #1 (logoutAction)
                  sLog.debug("Attempting to log user out");
                  String userName = request.getUserPrincipal().getName();
                  request.getSession().removeAttribute(SessionConstants.HTTP_USER_LIGHT);
                  request.getSession().invalidate();
                  if (sLog.isDebugEnabled()){
                  sLog.debug("attempting to see if session obj is really gone") ;
                  sLog.debug("value="+request.getSession().getAttribute(SessionConstants.HTTP_USER_LIGHT));
                  //the above will return null.. user obj is gone...for now
                  }
                  request.setAttribute("loggedOut", Boolean.TRUE);

                  Steps #2 and #3 (logoutServlet)
                  HttpServletRequest req = (HttpServletRequest)arg0;
                  HttpServletResponse res = (HttpServletResponse)arg1;
                  req.getSession().invalidate();
                  res.sendRedirect("/pages/common/logout.html");


                  In logout.html you can click link back to main url of system. There the code will check to see if a user is logged in... and guess what? The user is logged in. Code below:

                  Step #4
                  UserLight userLight = (UserLight)request.getSession().getAttribute(SessionConstants.HTTP_USER_LIGHT);
                  if (userLight != null) {
                  sLog.debug("Getting user session info from session");
                  //user details are in session
                  return userLight;
                  } else {//do something }

                  Am I insane or have I just missed something stupid?

                  • 6. Re: Remove Principal Object from Request
                    milder60

                    Ok here is what I do now.

                    In logoutAction (struts action class)
                    1. Call SessionManager.logout() which invalidates session
                    and removes the users session object (should be redundant I know)
                    2. redirect to a logoutServlet which AGAIN invalidates session (just to ensure I'm not crazy)
                    3. response.sendRedirct( loggedout.html);
                    4. Click a link back into the system and acutally finds the userobject again!!!

                    Step #1 (logoutAction)
                    sLog.debug("Attempting to log user out");
                    String userName = request.getUserPrincipal().getName();
                    request.getSession().removeAttribute(SessionConstants.HTTP_USER_LIGHT);
                    request.getSession().invalidate();
                    if (sLog.isDebugEnabled()){
                    sLog.debug("attempting to see if session obj is really gone") ;
                    sLog.debug("value="+request.getSession().getAttribute(SessionConstants.HTTP_USER_LIGHT));
                    //the above will return null.. user obj is gone...for now
                    }
                    request.setAttribute("loggedOut", Boolean.TRUE);

                    Steps #2 and #3 (logoutServlet)
                    HttpServletRequest req = (HttpServletRequest)arg0;
                    HttpServletResponse res = (HttpServletResponse)arg1;
                    req.getSession().invalidate();
                    res.sendRedirect("/pages/common/logout.html");


                    In logout.html you can click link back to main url of system. There the code will check to see if a user is logged in... and guess what? The user is logged in. Code below:

                    Step #4
                    UserLight userLight = (UserLight)request.getSession().getAttribute(SessionConstants.HTTP_USER_LIGHT);
                    if (userLight != null) {
                    sLog.debug("Getting user session info from session");
                    //user details are in session
                    return userLight;
                    } else {//do something }

                    Am I insane or have I just missed something stupid?

                    • 7. Re: Remove Principal Object from Request
                      milder60

                      Why can't I reply to this?

                      • 8. Re: Remove Principal Object from Request
                        milder60

                        Ooops... apologies. My posts weren't showing up and now they're coming in droves.

                        • 9. Re: Remove Principal Object from Request

                          > Am I insane or have I just missed something stupid?

                          None of the above (as far as i can tell ;-))

                          I don't see anything wrong in your code. Apart from that you should not use req.getSession().invalidate() a second time, because req.getSession() actually creates a session if there is not one already. Use req.getSession(false) instead.

                          But...
                          this still does not explain the behaviour you described. I don't get it, this should work. Maybe you'd attach your web.xml and the login-config.xml from the jboss conf directory. And please, log the session-id in step #1 and in step #4, so we can see whether it still is the same session (HttpSession.getId()).

                          Peter.

                          • 10. Re: Remove Principal Object from Request
                            milder60

                            Well I have a solution... but not what you'd expect. I ported all the EJB's to DAO's and moved to Tomcat where the logout works exactly as it should. Perhaps it has something to do with the way JBoss/Jetty handles JAAS logins? I'm using a simple JDBC login Realm under Tomcat and it seems to work as it should. V. weird. The only differences are the servlet container and the login method.