1 Reply Latest reply on Dec 14, 2010 10:11 PM by Ryan Samiley

    Redirect to previous View after Login

    Ryan Samiley Newbie

      The system I'm working on sends on out notification e-mails composed of a link users click on to get back the application view so the user can perform some action. Users are likely not logged in at the time so after the login I want the user redirected back to the original view listed in the e-mail.


      I tried this in components.xml:


      <event type="org.jboss.seam.security.notLoggedIn">
        <action execute="#{redirect.captureCurrentView}"/>
      </event>
      
      <event type="org.jboss.seam.security.postAuthenticate">
        <action execute="#{redirect.returnToCapturedView}"/>
      </event>



      It wasn't performing the redirect. I tried injecting the org.jboss.seam.faces.Redirect into my Authentication object but the viewId was always returning null. Is this because the Authentication object is Session scoped?


      I also tried creating my own view capturing object so it was easier to debug.


      @AutoCreate
      @Name("redirectWrapper")
      @Scope(ScopeType.CONVERSATION)
      @SuppressWarnings("serial")
      public class GotoEntityAction implements Serializable {
        @In (required  = true)
        private Redirect redirect;
      
        private String viewId;
      
        private Map<String, Object> parameters;
           
        public RedirectWrapper() {
          parameters = new HashMap<String, Object>(0);
        }
           
        public void captureCurrentView() {
          redirect.captureCurrentView();
      
          // Make a defensive copy
          String tmpString = redirect.getViewId();
          if (tmpString != null) {
            viewId = String.copyValueOf(tmpString.toCharArray());
          }
      
          // Make a defensive copy
          Map<String, Object> tmpMap = redirect.getParameters();
          if (tmpMap != null) {
            parameters = new HashMap<String, Object>(tmpMap);
          }
        }
           
        public boolean returnToCapturedView() {
          if (viewId == null) {
            return false;
          }
      
          // Set the view and parameters back to the ones we copied
          redirect.setViewId(viewId);
          Set<String> keys = parameters.keySet();
          for (String key : keys) {
            redirect.setParameter(key, parameters.get(key));
          }
                
          return redirect.returnToCapturedView();
        }
           
        public boolean shouldRedirect() {
          return viewId != null;
        }
      }



      I set this in the components.xml


      <event type="org.jboss.seam.security.notLoggedIn">
        <action execute="#{redirectWrapper.captureCurrentView}"/>
      </event>
      
      <event type="org.jboss.seam.security.postAuthenticate">
        <action execute="#{redirectWrapper.returnToCapturedView}"/>
      </event>



      I can set a break point at RedirectWrapper.captureCurrentView() and see everything works, but the problem with this is I get a completely new RedirectWrapper object when I try to inject it into my AuthenticationAction object so I lose all the captured view and parameter data. Also when I set a breakpoint at the RedirectWrapper.returnToCapturedView method is never called.


      What am I doing wrong?

        • 1. Re: Redirect to previous View after Login
          Ryan Samiley Newbie

          After toying with it more, I was wondering why the org.jboss.seam.security.postAuthenticate event never got called. I even played with the org.jboss.seam.security.loginSuccessful event and neither worked.


          I had to add the following to my authenticate method to force the event to get raised. After that it picked up the correct Redirect object or in my case the RedirectWrapper and successfully performed the redirect.


          @RaiseEvent("org.jboss.seam.security.loginSuccessful")




          This seems like a hack to me. What is the Seam best practice to get those events raised?