5 Replies Latest reply on Jun 26, 2008 11:27 AM by jamesjmp

    How to change the Session Timeout from Seam

    jakubhertyk

      Hello,


      I have a requirement for users which are not logged in to have one session timeout and users which do login have a longer timeout.  Currently in web.xml I have:



      <session-config>
           <!-- 
            * In minutes, so 60 = 1 hour
           -->
           <session-timeout>60</session-timeout>
      </session-config>
      



      So everyone by default gets a 1 hour timeout.  However, when the user logs in I wish to extend that timeout.  With the HttpSession you can override the timeout on login with:



      session.setMaxInactiveInterval(8 * 60 * 60);
      



      I don't want to give idling users a long timeout without logging in.  Is it possible to accomplish this with Seam?


      Thanks,



      Jakub

        • 1. Re: How to change the Session Timeout from Seam
          shane.bryzak

          Sure, just call ServletContexts.getInstance().getRequest().getSession() to get the session object.  You can even write an observer that extends/reduces the session timeout when the user successfully logs in or out.  Something like this should work:



          @Observer("org.jboss.seam.security.loginSuccessful")
          public void extendSessionTime()
          {
            ServletContexts.getInstance().getRequest().getSession().setMaxInactiveInterval(LONG_SESSION_TIME);
          }
          
          @Observer("org.jboss.seam.security.loggedOut")
          public void resetSessionTime()
          {
            ServletContexts.getInstance().getRequest().getSession().setMaxInactiveInterval(STD_SESSION_TIME);
          }


          • 2. Re: How to change the Session Timeout from Seam
            jakubhertyk

            Thanks for the reply.  I guess that both the approaches would work.  I tried the following:



            @Stateless
            @Name("authenticator")
            public class AuthenticatorAction implements Authenticator {
            
                 public boolean authenticate() {
                      ServletContexts instance = ServletContexts.getInstance();
                      HttpServletRequest request = instance.getRequest();
                      HttpSession session = request.getSession();
                      session.setMaxInactiveInterval(8 * 60 * 60);
                      return true;
                 }
            
            }
            



            But



            HttpServletRequest request = instance.getRequest();




            returns null.  Then I tried the Observer approach, and with:



            @Name("loginObserver")
            @Scope(ScopeType.SESSION)
            public class LoginObserver implements Serializable {
            
                 @Observer(Identity.EVENT_LOGIN_SUCCESSFUL)
                 public void changeSessionTimeout() {
                      ServletContexts instance = ServletContexts.getInstance();
                      HttpServletRequest request = instance.getRequest();
                      HttpSession session = request.getSession();
                      session.setMaxInactiveInterval(8 * 60 * 60);
                 }
            
            }
            



            I also get a null pointer on the HttpServletRequest.  Do I need any further annotations on the Classes?


            Thanks,


            Jakub

            • 3. Re: How to change the Session Timeout from Seam
              jakubhertyk

              Looks like it's a fix for 2.1.0.A1


              ServletContexts instance returns null request during JSF request
              JBSEAM-2505

              • 4. Re: How to change the Session Timeout from Seam

                I see JBSEAM-2505 is currently closed, but until it is available in a release I found this workaround:
                Instead of accesing to



                ServletContexts.instance().getRequest().getSession()
                



                try this:


                @Observer("org.jboss.seam.postAuthenticate")
                public void postAuthenticate() {
                HttpServletRequest request =
                                   (HttpServletRequest) FacesContext.getCurrentInstance()
                                     .getExternalContext().getRequest();
                
                ....
                
                log.info("Session - MaxInactiveInterval: " + request.getSession().getMaxInactiveInterval());
                                    log.info("Session - CreationTime: " + request.getSession().getCreationTime());
                                    log.info("Session - LastAccessedTime: " + request.getSession().getLastAccessedTime());
                ...
                }
                


                At least it works for me and avoid a null request.




                • 5. Re: How to change the Session Timeout from Seam

                  by the way, I have tested the following, and I would like to know if it has sense:


                  In my components.xml I have this setting:


                     <core:manager concurrent-request-timeout="10000"
                                    conversation-timeout="600000"
                                    conversation-id-parameter="cid"
                                    />
                  



                  The previous method, once authenticated, shows as MaxInactiveInterval a value of 1800.


                  If I add this setting to web.xml



                  
                       <session-config>
                            <session-timeout>10</session-timeout>
                       </session-config>
                  
                  


                  then MaxInactiveInterval has a value of 600.


                  I wonder these:
                  1.- why if there is no setting in web.xml, MaxInactiveInterval has a value of 1800?
                  2.- session-timeout config seems to be the main setting, so no matter conversation-timeout and concurrent-request-timeout, if session-timeout has expired the rest would die as well. that is logic, is that the official behaviour?


                  thanks in advance!