This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit d1211048a9b4a0cf9e968f1f7a3f8fd09c7c2d94
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Jun 27 23:05:52 2019 +0100

    Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=63531
    
    Refactor authenticators so that the session last accessed time is not
    updated if the cache attribute is set to false and FORM authentication
    is not being used.
---
 .../catalina/authenticator/AuthenticatorBase.java  | 87 ++++++++--------------
 .../catalina/authenticator/FormAuthenticator.java  | 36 ++++++++-
 webapps/docs/changelog.xml                         |  6 ++
 3 files changed, 70 insertions(+), 59 deletions(-)

diff --git a/java/org/apache/catalina/authenticator/AuthenticatorBase.java 
b/java/org/apache/catalina/authenticator/AuthenticatorBase.java
index eb9d35e..e67cd20 100644
--- a/java/org/apache/catalina/authenticator/AuthenticatorBase.java
+++ b/java/org/apache/catalina/authenticator/AuthenticatorBase.java
@@ -431,55 +431,13 @@ public abstract class AuthenticatorBase extends ValveBase
             }
         }
 
-        // Special handling for form-based logins to deal with the case
-        // where the login form (and therefore the "j_security_check" URI
-        // to which it submits) might be outside the secured area
-        String contextPath = this.context.getPath();
-        String requestURI = request.getDecodedRequestURI();
-        if (requestURI.startsWith(contextPath) &&
-            requestURI.endsWith(Constants.FORM_ACTION)) {
-            if (!authenticate(request, response, config)) {
-                if (log.isDebugEnabled())
-                    log.debug(" Failed authenticate() test ??" + requestURI );
-                return;
-            }
-        }
-
-        // Special handling for form-based logins to deal with the case where
-        // a resource is protected for some HTTP methods but not protected for
-        // GET which is used after authentication when redirecting to the
-        // protected resource.
-        // TODO: This is similar to the FormAuthenticator.matchRequest() logic
-        //       Is there a way to remove the duplication?
-        Session session = request.getSessionInternal(false);
-        if (session != null) {
-            SavedRequest savedRequest =
-                    (SavedRequest) 
session.getNote(Constants.FORM_REQUEST_NOTE);
-            if (savedRequest != null) {
-                String decodedRequestURI = request.getDecodedRequestURI();
-                if (decodedRequestURI != null &&
-                        decodedRequestURI.equals(
-                                savedRequest.getDecodedRequestURI())) {
-                    if (!authenticate(request, response)) {
-                        if (log.isDebugEnabled()) {
-                            log.debug(" Failed authenticate() test");
-                        }
-                        /*
-                         * ASSERT: Authenticator already set the appropriate
-                         * HTTP status code, so we do not have to do anything
-                         * special
-                         */
-                        return;
-                    }
-                }
-            }
-        }
+        boolean authRequired = isContinuationRequired(request);
 
         Realm realm = this.context.getRealm();
         // Is this request URI subject to a security constraint?
         SecurityConstraint[] constraints = 
realm.findSecurityConstraints(request, this.context);
 
-        if (constraints == null && !context.getPreemptiveAuthentication()) {
+        if (constraints == null && !context.getPreemptiveAuthentication() && 
!authRequired) {
             if (log.isDebugEnabled()) {
                 log.debug(" Not subject to any constraint");
             }
@@ -520,23 +478,25 @@ public abstract class AuthenticatorBase extends ValveBase
 
         // Since authenticate modifies the response on failure,
         // we have to check for allow-from-all first.
-        boolean authRequired;
-        if (constraints == null) {
-            authRequired = false;
-        } else {
-            authRequired = true;
-            for(int i = 0; i < constraints.length && authRequired; i++) {
-                if(!constraints[i].getAuthConstraint()) {
-                    authRequired = false;
-                } else if(!constraints[i].getAllRoles()) {
-                    String [] roles = constraints[i].findAuthRoles();
-                    if(roles == null || roles.length == 0) {
-                        authRequired = false;
+        boolean hasAuthConstraint = false;
+        if (constraints != null) {
+            hasAuthConstraint = true;
+            for (int i = 0; i < constraints.length && hasAuthConstraint; i++) {
+                if (!constraints[i].getAuthConstraint()) {
+                    hasAuthConstraint = false;
+                } else if (!constraints[i].getAllRoles()) {
+                    String[] roles = constraints[i].findAuthRoles();
+                    if (roles == null || roles.length == 0) {
+                        hasAuthConstraint = false;
                     }
                 }
             }
         }
 
+        if (!authRequired && hasAuthConstraint) {
+            authRequired = true;
+        }
+
         if (!authRequired && context.getPreemptiveAuthentication()) {
             authRequired =
                     
request.getCoyoteRequest().getMimeHeaders().getValue("authorization") != null;
@@ -593,6 +553,21 @@ public abstract class AuthenticatorBase extends ValveBase
     // ------------------------------------------------------ Protected Methods
 
     /**
+     * Does this authenticator require that {@link #authenticate(Request,
+     * HttpServletResponse)} is called to continue an authentication process
+     * that started in a previous request?
+     *
+     * @param request The request currently being processed
+     *
+     * @return {@code true} if authenticate() must be called, otherwise
+     *         {@code false}
+     */
+    protected boolean isContinuationRequired(Request request) {
+        return false;
+    }
+
+
+    /**
      * Look for the X509 certificate chain in the Request under the key
      * <code>javax.servlet.request.X509Certificate</code>. If not found, 
trigger
      * extracting the certificate chain from the Coyote request.
diff --git a/java/org/apache/catalina/authenticator/FormAuthenticator.java 
b/java/org/apache/catalina/authenticator/FormAuthenticator.java
index 809556e..5b55664 100644
--- a/java/org/apache/catalina/authenticator/FormAuthenticator.java
+++ b/java/org/apache/catalina/authenticator/FormAuthenticator.java
@@ -352,13 +352,43 @@ public class FormAuthenticator
     }
 
 
+    // ------------------------------------------------------ Protected Methods
+
     @Override
-    protected String getAuthMethod() {
-        return HttpServletRequest.FORM_AUTH;
+    protected boolean isContinuationRequired(Request request) {
+        // Special handling for form-based logins to deal with the case
+        // where the login form (and therefore the "j_security_check" URI
+        // to which it submits) might be outside the secured area
+        String contextPath = this.context.getPath();
+        String decodedRequestURI = request.getDecodedRequestURI();
+        if (decodedRequestURI.startsWith(contextPath) &&
+                decodedRequestURI.endsWith(Constants.FORM_ACTION)) {
+            return true;
+        }
+
+        // Special handling for form-based logins to deal with the case where
+        // a resource is protected for some HTTP methods but not protected for
+        // GET which is used after authentication when redirecting to the
+        // protected resource.
+        // TODO: This is similar to the FormAuthenticator.matchRequest() logic
+        // Is there a way to remove the duplication?
+        Session session = request.getSessionInternal(false);
+        if (session != null) {
+            SavedRequest savedRequest = (SavedRequest) 
session.getNote(Constants.FORM_REQUEST_NOTE);
+            if (savedRequest != null &&
+                    
decodedRequestURI.equals(savedRequest.getDecodedRequestURI())) {
+                return true;
+            }
+        }
+
+        return false;
     }
 
 
-    // ------------------------------------------------------ Protected Methods
+    @Override
+    protected String getAuthMethod() {
+        return HttpServletRequest.FORM_AUTH;
+    }
 
 
     /**
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 64db49f..11afd1e 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -117,6 +117,12 @@
         <code>RequestDispatcher</code>. The requested target path is logged as 
a
         warning since this is an application error. (markt)
       </add>
+      <fix>
+        <bug>63531</bug>: Refactor authenticators so that the session last
+        accessed time is not updated if the cache attribute is set to
+        <code>false</code> and <code>FORM</code> authentication is not being
+        used. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to