craigmcc    01/07/11 16:39:51

  Modified:    catalina/src/share/org/apache/catalina/authenticator
                        Constants.java FormAuthenticator.java
  Log:
  Update form-based login processing to be consitent with the 2.3 PFD2 spec.
  In particular, Catalina now uses redirects (instead of internal forwards)
  to switch to the original request page, as required in Section 12.5.3,
  Step 7.  Thanks also to Vincente Salvador for a very helpful analysis of
  what was going on, and what the recommended correction should be.
  
  PR: Bugzilla #853
  Submitted by: [EMAIL PROTECTED]
  
  Revision  Changes    Path
  1.3       +5 -3      
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/Constants.java
  
  Index: Constants.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/Constants.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Constants.java    2000/10/06 05:10:16     1.2
  +++ Constants.java    2001/07/11 23:39:49     1.3
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/Constants.java,v
 1.2 2000/10/06 05:10:16 craigmcc Exp $
  - * $Revision: 1.2 $
  - * $Date: 2000/10/06 05:10:16 $
  + * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/Constants.java,v
 1.3 2001/07/11 23:39:49 craigmcc Exp $
  + * $Revision: 1.3 $
  + * $Date: 2001/07/11 23:39:49 $
    *
    * ====================================================================
    *
  @@ -85,6 +85,8 @@
       public static final String FORM_KEY =
        "org.apache.catalina.security.REQUEST";
       public static final String FORM_PASSWORD = "j_password";
  +    public static final String FORM_PRINCIPAL =
  +        "org.apache.catalina.security.PRINCIPAL";
       public static final String FORM_USERNAME = "j_username";
   
       // Cookie name for single sign on support
  
  
  
  1.8       +111 -17   
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/FormAuthenticator.java
  
  Index: FormAuthenticator.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/FormAuthenticator.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- FormAuthenticator.java    2001/03/14 02:17:20     1.7
  +++ FormAuthenticator.java    2001/07/11 23:39:50     1.8
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/FormAuthenticator.java,v
 1.7 2001/03/14 02:17:20 craigmcc Exp $
  - * $Revision: 1.7 $
  - * $Date: 2001/03/14 02:17:20 $
  + * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/authenticator/FormAuthenticator.java,v
 1.8 2001/07/11 23:39:50 craigmcc Exp $
  + * $Revision: 1.8 $
  + * $Date: 2001/07/11 23:39:50 $
    *
    * ====================================================================
    *
  @@ -88,7 +88,7 @@
    * Authentication, as described in the Servlet API Specification, Version 2.2.
    *
    * @author Craig R. McClanahan
  - * @version $Revision: 1.7 $ $Date: 2001/03/14 02:17:20 $
  + * @version $Revision: 1.8 $ $Date: 2001/07/11 23:39:50 $
    */
   
   public final class FormAuthenticator
  @@ -139,9 +139,18 @@
                                LoginConfig config)
        throws IOException {
   
  +        if (debug < 99)
  +            debug = 99;
  +
  +        // References to objects we will need later
  +        HttpServletRequest hreq =
  +          (HttpServletRequest) request.getRequest();
  +        HttpServletResponse hres =
  +          (HttpServletResponse) response.getResponse();
  +        Session session = null;
  +
        // Have we already authenticated someone?
  -     Principal principal =
  -         ((HttpServletRequest) request.getRequest()).getUserPrincipal();
  +     Principal principal = hreq.getUserPrincipal();
        if (principal != null) {
               if (debug >= 1)
                   log("Already authenticated '" +
  @@ -149,21 +158,38 @@
            return (true);
           }
   
  +        // Is this the re-submit of the original request URI after successful
  +        // authentication?  If so, forward the *original* request instead.
  +        if (matchRequest(request)) {
  +            session = getSession(request);
  +            if (debug >= 1)
  +                log("Restore request from session '" + session.getId() + "'");
  +            principal = (Principal)
  +              session.getSession().getAttribute(Constants.FORM_PRINCIPAL);
  +            register(request, response, principal, Constants.FORM_METHOD);
  +            if (restoreRequest(request, session)) {
  +                if (debug >= 1)
  +                    log("Proceed to restored request");
  +                return (true);
  +            } else {
  +                if (debug >= 1)
  +                    log("Restore of original request failed");
  +                hres.sendError(HttpServletResponse.SC_BAD_REQUEST);
  +                return (false);
  +            }
  +        }
  +
        // Acquire references to objects we will need to evaluate
  -     HttpServletRequest hreq =
  -         (HttpServletRequest) request.getRequest();
  -     HttpServletResponse hres =
  -         (HttpServletResponse) response.getResponse();
        String contextPath = hreq.getContextPath();
        String requestURI = hreq.getRequestURI();
        response.setContext(request.getContext());
  -        Session session = null;
   
        // Is this a request for the login page itself?  Test here to avoid
        // displaying it twice (from the user's perspective) -- once because
        // of the "save and redirect" and once because of the "restore and
        // redirect" performed below.
  -     if (requestURI.equals(contextPath + config.getLoginPage())) {
  +        String loginURI = contextPath + config.getLoginPage();
  +     if (requestURI.equals(loginURI)) {
               if (debug >= 1)
                   log("Requesting login page normally");
            return (true);      // Display the login page in the usual manner
  @@ -180,8 +206,10 @@
               if (debug >= 1)
                   log("Save request in session '" + session.getId() + "'");
            saveRequest(request, session);
  -         request.setRequestURI(contextPath + config.getLoginPage());
  -         return (true);      // Display the login page in the usual manner
  +            if (debug >= 1)
  +                log("Redirect to login page '" + loginURI + "'");
  +            hres.sendRedirect(hres.encodeRedirectURL(loginURI));
  +            return (false);
        }
   
        // Yes -- Validate the specified credentials and redirect
  @@ -191,14 +219,28 @@
        String password = hreq.getParameter(Constants.FORM_PASSWORD);
        principal = realm.authenticate(username, password);
        if (principal == null) {
  +            String errorURI = contextPath + config.getErrorPage();
               if (debug >= 1)
  -                log("Authentication failed, show error page");
  -         request.setRequestURI(contextPath + config.getErrorPage());
  -         return (true);      // Display the error page in the usual manner
  +                log("Redirect to error page '" + errorURI + "'");
  +            hres.sendRedirect(hres.encodeRedirectURL(errorURI));
  +            return (false);
        }
   
  +        // Save the authenticated Principal in our session
  +        if (session == null)
  +            session = getSession(request);
  +        session.getSession().setAttribute(Constants.FORM_PRINCIPAL, principal);
  +
  +        // Redirect the user to the original request URI (which will cause
  +        // the original request to be restored)
  +        requestURI = savedRequestURI(session);
  +        if (debug >= 1)
  +            log("Redirecting to '" + requestURI + "'");
  +        hres.sendRedirect(hres.encodeRedirectURL(requestURI));
  +        return (false);
   
        // Restore this request and redirect to the original request URI
  +        /*
           session = getSession(request, true);
           if (debug >= 1)
               log("restore request from session '" + session.getId() + "'");
  @@ -214,6 +256,7 @@
               //           hres.flushBuffer();
            return (false);
        }
  +        */
   
       }
   
  @@ -222,6 +265,39 @@
   
   
       /**
  +     * Does this request match the saved one (so that it must be the redirect
  +     * we signalled after successful authentication?
  +     *
  +     * @param request The request to be verified
  +     */
  +    private boolean matchRequest(HttpRequest request) {
  +
  +      // Has a session been created?
  +      Session session = getSession(request, false);
  +      if (session == null)
  +          return (false);
  +
  +      // Is there a saved request?
  +      SavedRequest sreq = (SavedRequest)
  +        session.getSession().getAttribute(Constants.FORM_KEY);
  +      if (sreq == null)
  +          return (false);
  +
  +      // Is there a saved principal?
  +      if (session.getSession().getAttribute(Constants.FORM_PRINCIPAL) == null)
  +          return (false);
  +
  +      // Does the request URI match?
  +      HttpServletRequest hreq = (HttpServletRequest) request.getRequest();
  +      String requestURI = hreq.getRequestURI();
  +      if (requestURI == null)
  +          return (false);
  +      return (requestURI.equals(sreq.getRequestURI()));
  +
  +    }
  +
  +
  +    /**
        * Restore the original request from information stored in our session.
        * If the original request is no longer present (because the session
        * timed out), return <code>false</code>; otherwise, return
  @@ -236,6 +312,7 @@
        SavedRequest saved = (SavedRequest)
            session.getSession().getAttribute(Constants.FORM_KEY);
        session.getSession().removeAttribute(Constants.FORM_KEY);
  +        session.getSession().removeAttribute(Constants.FORM_PRINCIPAL);
        if (saved == null)
            return (false);
   
  @@ -318,6 +395,23 @@
   
        // Stash the SavedRequest in our session for later use
        session.getSession().setAttribute(Constants.FORM_KEY, saved);
  +
  +    }
  +
  +
  +    /**
  +     * Return the request URI from the saved request.
  +     *
  +     * @param session Our current session
  +     */
  +    private String savedRequestURI(Session session) {
  +
  +        SavedRequest saved =
  +          (SavedRequest) session.getSession().getAttribute(Constants.FORM_KEY);
  +        if (saved == null)
  +            return (null);
  +        else
  +            return (saved.getRequestURI());
   
       }
   
  
  
  

Reply via email to