0 Replies Latest reply on Oct 20, 2010 8:40 AM by aimee

    Security - External Authorization - How to Capture Originally Requested Page? (OpenID modification)

    aimee

      Our first Seam app is going to run on a corporate intranet and we must authenticate our users against another internal site that returns a cookie to us. I looked at the OpenID example and adapted it to use with our app.
      The problem I'm running into is redirecting the user to the originally requested page. The OpenID example only has one page and is explicitly directing the user back to that main page after a successful authentication.


      Scenarios:


      1)  user requests http://www.ourapp.com: Seam redirects to login.xhtml, login button is pushed, the phase listener redirects to external authorization site, auth cookie is returned, we process it and redirect to our app's home page  - all is fine 


      2) user clicks a link in an email that requests a login-required page such as http://www.ourapp.com/anotherPage.seam?queryParms   Seam immediately redirects the user to our app's login page, login button is pushed, etc   This is the situation in which I need to capture the originally requested page and query parameters


      I've looked through the all the contexts (Event, Conversation, Page, Application), the Seam source code (Redirect), the Seam forums, and several books and can't figure out how to access the name of originally requested page and query parameters. If we use only Seam security for authentication against our own user/password tables, page redirects work fine. However, in production we cannot have user/password tables; we must use our company's intranet authorization service.


      We've also tried extending Identity and modifying the login method, but we still encounter the same problem when the user requests a specific page.


      I've spent days on this already and tried so many things that my head is still spinning. Can anyone give me some suggestions? Thanks in advance.


      In the Render Response phase listener


      public void beforePhase(PhaseEvent event) {
               log.info("beforePhase BEGIN ");
              String viewId = Pages.getCurrentViewId();//this is always the login page
              log.info("     viewId=" + viewId);
              HttpServletRequest request =HttpServletRequest)event.getFacesContext().getExternalContext().getRequest();
              if (viewId==null || !viewId.startsWith("/openid.")) {
                  return;
              }
              OpenId openid = (OpenId) Component.getInstance(OpenId.class);        
              openid.verify();        
              Pages.handleOutcome(event.getFacesContext(), null, OpenId.RETURN_TO_PAGE);
              //Redirect.instance().returnToCapturedView(); //this does not work       
              log.info("beforePhase END ");
      }
      



      In OpenId login



      public void login() throws IOException {
                log.info("login BEGIN ");
                validatedId = null;
                String returnToUrl = returnToUrl();
                String url = authRequest(id, returnToUrl);
                if (url != null) {
                     Redirect redirect = Redirect.instance();
                     redirect.captureCurrentView();
                     FacesManager.instance().redirectToExternalURL(url);
                }
                log.info("login END ");
           }
      



      In pages.xml


      <pages xmlns="http://jboss.com/products/seam/pages"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.2.xsd"
        no-conversation-view-id="/main.xhtml" login-view-id="/home.xhtml">
      
           <page view-id="/openid.xhtml">
              <navigation evaluate="#{openid.loginImmediately()}">
                  <rule if-outcome="true">
                      <redirect view-id="/main.xhtml">
                          <message>OpenID login successful...</message>
                      </redirect>
                  </rule>
                  <rule if-outcome="false">
                      <redirect view-id="/main.xhtml">
                          <message>OpenID login rejected...</message>
                      </redirect>
                  </rule>
              </navigation>
          </page>
      
          <page view-id="/main.xhtml">
              <rewrite pattern="/" />
      
      <page view-id="/page2.xhtml" login-required="true" />
          <exception class="javax.faces.application.ViewExpiredException">
              <redirect view-id="/main.xhtml">
                  <message severity="warn">Your session expired.  Please try again.</message>
              </redirect>
          </exception>
      </pages>
      



      In Components.xml




      <core:init debug="true" jndi-pattern="@jndiPattern@"/>
          <web:rewrite-filter />
          <transaction:ejb-transaction />
         <security:identity authenticate-method="#{authenticator.authenticate}" remember-me="true"/>
       <event type="org.jboss.seam.security.notLoggedIn">
            <action execute="#{redirect.captureCurrentView}" />      
         </event>
         <core:manager concurrent-request-timeout="500"
                       conversation-timeout="120000"
                       conversation-id-parameter="cid"
                       parent-conversation-id-parameter="pid"/>
         <!-- Make sure this URL pattern is the same as that used by the Faces Servlet -->
         <web:hot-deploy-filter url-pattern="*.seam"/>
         <persistence:managed-persistence-context name="entityManager" auto-create="true"
                            persistence-unit-jndi-name="java:/CspSandboxEntityManagerFactory"/>