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

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


The following commit(s) were added to refs/heads/8.5.x by this push:
     new d003ac1  BZ 63636: Context#findRoleMapping() never called in 
StandardWrapper#findSecurityReference()
d003ac1 is described below

commit d003ac14caae9269f128e1722a9d826538597af6
Author: Michael Osipov <micha...@apache.org>
AuthorDate: Mon Aug 5 21:32:58 2019 +0200

    BZ 63636: Context#findRoleMapping() never called in 
StandardWrapper#findSecurityReference()
---
 java/org/apache/catalina/core/StandardWrapper.java | 14 ++++-
 java/org/apache/catalina/realm/RealmBase.java      |  2 +-
 .../apache/catalina/core/TestStandardWrapper.java  | 67 ++++++++++++++++++++++
 webapps/docs/changelog.xml                         |  4 ++
 4 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/catalina/core/StandardWrapper.java 
b/java/org/apache/catalina/core/StandardWrapper.java
index a12ea42..d0dd4b2 100644
--- a/java/org/apache/catalina/core/StandardWrapper.java
+++ b/java/org/apache/catalina/core/StandardWrapper.java
@@ -922,14 +922,26 @@ public class StandardWrapper extends ContainerBase
      */
     @Override
     public String findSecurityReference(String name) {
+        String reference = null;
 
         referencesLock.readLock().lock();
         try {
-            return references.get(name);
+            reference = references.get(name);
         } finally {
             referencesLock.readLock().unlock();
         }
 
+        // If not specified on the Wrapper, check the Context
+        if (getParent() instanceof Context) {
+            Context context = (Context) getParent();
+            if (reference != null) {
+                reference = context.findRoleMapping(reference);
+            } else {
+                reference = context.findRoleMapping(name);
+            }
+        }
+
+        return reference;
     }
 
 
diff --git a/java/org/apache/catalina/realm/RealmBase.java 
b/java/org/apache/catalina/realm/RealmBase.java
index eaa49aa..dd1761c 100644
--- a/java/org/apache/catalina/realm/RealmBase.java
+++ b/java/org/apache/catalina/realm/RealmBase.java
@@ -922,7 +922,7 @@ public abstract class RealmBase extends LifecycleMBeanBase 
implements Realm {
      */
     @Override
     public boolean hasRole(Wrapper wrapper, Principal principal, String role) {
-        // Check for a role alias defined in a <security-role-ref> element
+        // Check for a role alias
         if (wrapper != null) {
             String realRole = wrapper.findSecurityReference(role);
             if (realRole != null) {
diff --git a/test/org/apache/catalina/core/TestStandardWrapper.java 
b/test/org/apache/catalina/core/TestStandardWrapper.java
index 30f24c1..9358345 100644
--- a/test/org/apache/catalina/core/TestStandardWrapper.java
+++ b/test/org/apache/catalina/core/TestStandardWrapper.java
@@ -18,6 +18,7 @@ package org.apache.catalina.core;
 
 import java.io.File;
 import java.io.IOException;
+import java.security.Principal;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -48,6 +49,7 @@ import org.junit.Test;
 import org.apache.catalina.Context;
 import org.apache.catalina.Wrapper;
 import org.apache.catalina.authenticator.BasicAuthenticator;
+import org.apache.catalina.realm.MessageDigestCredentialHandler;
 import org.apache.catalina.startup.TesterMapRealm;
 import org.apache.catalina.startup.Tomcat;
 import org.apache.catalina.startup.TomcatBaseTest;
@@ -235,6 +237,71 @@ public class TestStandardWrapper extends TomcatBaseTest {
         Assert.assertTrue(bc.toString().contains("00-OK"));
     }
 
+    @Test
+    public void testRoleMappingInEngine() throws Exception {
+        doTestRoleMapping("engine");
+    }
+
+    @Test
+    public void testRoleMappingInHost() throws Exception {
+        doTestRoleMapping("host");
+    }
+
+    @Test
+    public void testRoleMappingInContext() throws Exception {
+        doTestRoleMapping("context");
+    }
+
+    private void doTestRoleMapping(String realmContainer)
+            throws Exception {
+        // Setup Tomcat instance
+        Tomcat tomcat = getTomcatInstance();
+
+        // No file system docBase required
+        Context ctx = tomcat.addContext("", null);
+        ctx.addRoleMapping("testRole2", "very-complex-role-name");
+        /* We won't map "testRole3" to "another-very-complex-role-name" to make
+         * it fail intentionally.
+         */
+
+        Wrapper wrapper = Tomcat.addServlet(ctx, "servlet", 
TestServlet.class.getName());
+        ctx.addServletMappingDecoded("/", "servlet");
+
+        TesterMapRealm realm = new TesterMapRealm();
+        MessageDigestCredentialHandler ch = new 
MessageDigestCredentialHandler();
+        ch.setAlgorithm("SHA");
+        realm.setCredentialHandler(ch);
+
+        /* Attach the realm to the appropriate container, but role mapping must
+         * always succeed because it is evaluated at context level.
+         */
+        if (realmContainer.equals("engine")) {
+            tomcat.getEngine().setRealm(realm);
+        } else if (realmContainer.equals("host")) {
+            tomcat.getHost().setRealm(realm);
+        } else if (realmContainer.equals("context")) {
+            ctx.setRealm(realm);
+        } else {
+            throw new IllegalArgumentException("realmContainer is invalid");
+        }
+
+        realm.addUser("testUser", ch.mutate("testPwd"));
+        realm.addUserRole("testUser", "testRole1");
+        realm.addUserRole("testUser", "very-complex-role-name");
+        realm.addUserRole("testUser", "another-very-complex-role-name");
+
+        tomcat.start();
+
+        Principal p = realm.authenticate("testUser", "testPwd");
+
+        Assert.assertNotNull(p);
+        Assert.assertEquals("testUser", p.getName());
+        Assert.assertTrue(realm.hasRole(wrapper, p, "testRole1"));
+        Assert.assertTrue(realm.hasRole(wrapper, p, "testRole2"));
+        Assert.assertTrue(realm.hasRole(wrapper, p, "very-complex-role-name"));
+        Assert.assertFalse(realm.hasRole(wrapper, p, "testRole3"));
+    }
+
     private void doTestSecurityAnnotationsAddServlet(boolean useCreateServlet)
             throws Exception {
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index ac43803..0839a76 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -101,6 +101,10 @@
         and a request does not map to any of the other deployed Contexts. Patch
         provided by Jop Zinkweg. (markt)
       </fix>
+      <fix>
+        <bug>63636</bug>: <code>Context.findRoleMapping()</code> never called
+        in <code>StandardWrapper.findSecurityReference()</code>. (michaelo)
+      </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