Announcement Announcement Module
Collapse
No announcement yet.
custom login messages when session expires Page Title Module
Move Remove Collapse
This topic is closed
X
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • custom login messages when session expires

    Hi all

    When acegi redirects a user to the login page upon httpsession expiry, i'd like to display a 'session expired' message, so they know why they are now at the login page

    is there a point somewhere where i can trap the 'session has expired' event and maybe set a request attribute or request http param immediately before the user is directed to the login page?

    i'm guessing this is a fairly common requirement. what are the general best practices for implementing "your session has expired. please login again" functionality?

    thanks

  • #2
    If someone can point me in the right direction that would be great.

    Essentially, I'm trying to determine the difference between
    1. when the user tries to access a secured resource and hasnt logged in
    2. when the user tries to access a secured resource and their http session has expired

    If (2) occurs above, I'd like to be able to tell the login page to display a 'your session has expired' message.

    Comment


    • #3
      Sessions are maintained by the container and once one is destroyed, there is no way to determine the difference between a request from a user starting a new session and one from an existing user using a timed out session.

      You could set a session cookie and detect that when the user is forced to log in again. Using a synchronizer token (or some similar request parameter) would also give you the same behaviour.

      Comment


      • #4
        I wrote a custom servlet filter that queries the HTTP request to see if it passed a session id and if that session id is valid. If it's not, I redirect to the login screen, passing a parameter that my JSP can detect to display a "session timed out" message.

        Here's the code for the filter:

        Code:
        import org.springframework.beans.factory.InitializingBean;
        
        import org.springframework.util.Assert;
        
        import java.io.IOException;
        
        import javax.servlet.Filter;
        import javax.servlet.FilterChain;
        import javax.servlet.FilterConfig;
        import javax.servlet.ServletException;
        import javax.servlet.ServletRequest;
        import javax.servlet.ServletResponse;
        import javax.servlet.http.HttpServletRequest;
        import javax.servlet.http.HttpServletResponse;
        import javax.servlet.http.HttpSession;
        
        
        public class SessionExpirationFilter implements Filter, InitializingBean {
            //~ Instance fields ================================================================================================
        
            private String expiredUrl;
        
            //~ Methods ========================================================================================================
        
            public void afterPropertiesSet() throws Exception {
                Assert.hasText(expiredUrl, "ExpiredUrl required");
            }
        
            /**
             * Does nothing. We use IoC container lifecycle services instead.
             */
            public void destroy() {}
        
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
                Assert.isInstanceOf(HttpServletRequest.class, request, "Can only process HttpServletRequest");
                Assert.isInstanceOf(HttpServletResponse.class, response, "Can only process HttpServletResponse");
        
                HttpServletRequest httpRequest = (HttpServletRequest) request;
                HttpServletResponse httpResponse = (HttpServletResponse) response;
                
                HttpSession session = httpRequest.getSession(false);
        
                if (session == null &&
                    httpRequest.getRequestedSessionId() != null &&
                    !httpRequest.isRequestedSessionIdValid())
                {    
                    String targetUrl = httpRequest.getContextPath() + expiredUrl;
                    httpResponse.sendRedirect(httpResponse.encodeRedirectURL(targetUrl));
                    return;
                }
        
                chain.doFilter(request, response);
            }
        
            /**
             * Does nothing. We use IoC container lifecycle services instead.
             *
             * @param arg0 ignored
             *
             * @throws ServletException ignored
             */
            public void init(FilterConfig arg0) throws ServletException {}
        
            public void setExpiredUrl(String expiredUrl) {
                this.expiredUrl = expiredUrl;
            }
        }
        Then I make sure that the SessionExpirationFilter is the first filter applied to protected resources. Note that the login page (the page that a session expiration will redirect to) is NOT protected by SessionExpirationFilter (otherwise you end up with an infinite redirect loop).

        Code:
        <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
            <property name="filterInvocationDefinitionSource">
                <value>
        CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
        PATTERN_TYPE_APACHE_ANT
        /login.spring*=httpSessionContextIntegrationFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
        /**=sessionExpirationFilter,httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
                </value>
            </property>
        </bean>
        
        ...
        
        <bean id="sessionExpirationFilter" class="SessionExpirationFilter">
            <property name="expiredUrl" value="/login.spring?login_error=2"/>
        </bean>
        
        ...
        Then in my login page, I just check for the error parameter that I configured.

        Code:
        <c:if test="${param.login_error == 2}">
        	<br>
        	<h2 class="red">Your session has timed out.</h2>
        </c:if>
        
        ...
        It's been working so far.

        ---
        Christopher Pierce
        Last edited by macob; Jun 3rd, 2008, 12:15 PM. Reason: bug in configuration example, missing wildcard in URL

        Comment


        • #5
          Looks pretty good. So everything you need is actually already there in the servlet API. In that case, we should perhaps look at adding support detecting expired sessions in HttpSessionContextIntegrationFilter sometime in the future.

          Comment


          • #6
            I'm not sure if it would make any sense, but my first instinct would be to add a sessionTimeoutUrl property to AuthenticationProcessingFilter

            Comment


            • #7
              Is there JIRA on this new functionality?

              Is there JIRA on this new functionality?

              Comment


              • #8
                I would be an outstanding functionality, indeed, dear Watson.

                Comment


                • #9
                  Just wondering is this functionality on the roadmap for spring security?

                  Comment


                  • #10
                    Abandonment

                    It seems, my fellow forum colleagues, that abandonment has fell upon us.

                    Comment


                    • #11
                      Page redirection after session timeout

                      I want my pages to be redirected when accessed after a timeout. I have specified the session time out in web.xml. I can see that sessino timeout is happening, because I see that my pages are not getting updated after the timeout. But I need to redirect my page to login page, which is not happening.
                      I tried setting expired-url in concurrent-session-control tag in applicatin context xml file, but it didnot work. After various other trials, I found this article and implemented a custom filter , SessionExpiryFilter as mentioned in the article.

                      I find that, I never get session value as null after timeout, but I am pretty sure that timeout is happening. Since I am not able to identify that timeout has happened frmo the value of session, I am not able to redirect to the login page from the filter. I tried setting the listner for HttpSessionEvent in web.xml, but still, the filter does not get the session value as null after timeout.

                      When I put the filter as the last one in the chain, the filter does not get invoked at all.

                      Is there a mechanism that Spring provides to implement page redirection on session timeout?

                      I have also posted another message in this forum (thread number 61091)

                      Comment


                      • #12
                        I am trying to solve exactly the same problem in my Spring MVC application and I followed the suggestion provided. I have created the custom session filter class and configured the xml files. But for some reason, my session filter never gets called. Interestingly, the expired session seems to be detected by spring and automatically redirects the user to the login page. But the custome 'session expired' message is not showing up.

                        Comment


                        • #13
                          is latest HttpSessioncontextIntegrationfilter supporing session timeout..?
                          i am debugging this class.But i couldn't find ....
                          So still do we need to write our own filter for checking session timeout ..?
                          Please reply
                          Thanks

                          Comment


                          • #14
                            relogin to CAS when session expires

                            I have a spring application implemented with Spring Security and CAS. In web.xml file, I have difined session event listener and session timeout parameter.
                            ~~~~~~~~~
                            <listener>
                            <listenerclass>
                            org.jasig.cas.client.session.SingleSignOutHttpSess ionListener
                            </listener-class>
                            </listener>

                            <session-config>
                            <session-timeout>5</session-timeout>
                            </session-config>
                            ~~~~~~~~~

                            Now after the application session timeout, I need to single sign the user out of CAS, and if he/she wants to access secured resource, she/he needs to be reauthenticated. Is that already implemented in spring-security-cas-client? Or do I need to use something like Macob's filter?

                            Thanks!

                            -Xuejin

                            Comment


                            • #15
                              Looks like support has been added in Spring Security 3.0.0 M2

                              Support for session timeout detection

                              Comment

                              Working...
                              X