2 Replies Latest reply on Feb 22, 2010 4:14 PM by fesi

    RememberMe with autoLogin mode (token based) still redirects to login page

    fesi

      I'm using Seam 2.2.0 and want to add the auto login feature to our application. I therefore added the following fragment to components.xml:


      <security:identity authenticate-method="#{authenticator.authenticate}" />
      <security:remember-me mode="autoLogin" />
      <event type="org.jboss.seam.security.notLoggedIn">
          <action execute="#{redirect.captureCurrentView}" />
          <action execute="#{identity.tryLogin}" />
      </event>
      <event type="org.jboss.seam.security.postAuthenticate">
          <action execute="#{redirect.returnToCapturedView}" />
      </event>
      

         
      We use our own token store, that's why it is not configuered here.


      As soon as a not yet logged in user providing the token cookie tries to access a page having the login-required attribute set to true, the quiet login is executed, the redirect component executes returntoCapturedView() but then seam still redirects to the login page (the user being logged in already).


      In the pages component (org.jboss.seam.navigation.Pages) I found the following code:


      public void redirectToLoginView()
      {
         notLoggedIn();
         
         String loginViewId = getLoginViewId();
         if (loginViewId==null)
         {
            throw new NotLoggedInException();
         }
         else
         {
            Manager.instance().redirect(loginViewId);
         }
      }
      



      notLoggedIn() just fires the notLoggedIn event. As a result of this event, the redirect component captures the current view and the remember-me component performs the quiet login (as a result of identity.tryLogin). After the quiet login the postAuthenticate event is fired triggering the redirect component to execute its returnToCapturedView method. So far so good. But now the notLoggedIn() method returns and the pages component redirects to the logn page.


      Did I miss something in the documentation chapter 15.3.5? How can I suppress the redirect to the login page?

        • 1. Re: RememberMe with autoLogin mode (token based) still redirects to login page
          fesi

          I see two possible work-arounds for this problem:


          1. Replace the Pages component by your own implementation, which replaces the method isLoginRedirectRequired(String viewId, Page page) as follows:



          Old:
          private boolean isLoginRedirectRequired(String viewId, Page page)
          {
             return page.isLoginRequired() && 
                   !viewId.equals( getLoginViewId() ) && 
                   !Identity.instance().isLoggedIn();
          }
          
          New:
          private boolean isLoginRedirectRequired(String viewId, Page page)
          {
             if (page.isLoginRequired() && !viewId.equals( getLoginViewId() ) && !Identity.instance().isLoggedIn()) {
                notLoggedIn();
                if (!Identity.instance().isLoggedIn()) {
                   return true;
                }
             }
             return false;
          }




          Unfortunately this method is private, so you cannot just override it :-(


          2. Add a page action to the login page, which fires an org.jboss.seam.security.loginSuccessful event, if the user is already logged in, resulting in a call to Redirect.redirectToCapturedView().


          I chose the second approach. (Note: I replaced the org.jboss.seam.security.postAuthenticate event from the original snippet by the org.jboss.seam.security.loginSuccessful event.)


          Felix

          • 2. Re: RememberMe with autoLogin mode (token based) still redirects to login page
            fesi

            A similar problem arises when a component is secured using the @Restrict annotation. The Seam online documentation recommends to add an exception handler for the NotLoggedInException, redirecting to the login page.



            <exception class="org.jboss.seam.security.NotLoggedInException" log="false">
                <redirect view-id="/view/core/login.xhtml" />
            </exception>




            Before a call to a method of the secured component is executed, Seam calls Identity.checkRestriction(elExpr), which evaluates the EL expression defined in the @Restrict annotation. If the check fails because the user is not logged in, the org.jboss.seam.security.notLoggedIn event is fired followed by the NotLoggedInException being thrown. If the auto-login process is triggered by the org.jboss.seam.security.notLoggedIn event resulting in the user being logged in, the NotLoggedInException should no longer be thrown, but it is, thus redirecting the user to the login page again. This is quite annoying and the log-files are filled up with huge stack traces caused by the NotLoggedInException, which doesn't really indicate an exceptional state in this particular case.


            Felix