This is an automated email from the ASF dual-hosted git repository. michaelo pushed a commit to branch BZ-63636/tomcat-7.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 34dbc57b3e665e32ad1f891a7bfbd7240f38896e 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 | 63 ++++++++++++++++++++++ webapps/docs/changelog.xml | 6 ++- 4 files changed, 82 insertions(+), 3 deletions(-) diff --git a/java/org/apache/catalina/core/StandardWrapper.java b/java/org/apache/catalina/core/StandardWrapper.java index 774d393..ff83ead 100644 --- a/java/org/apache/catalina/core/StandardWrapper.java +++ b/java/org/apache/catalina/core/StandardWrapper.java @@ -1006,14 +1006,26 @@ public class StandardWrapper extends ContainerBase */ @Override public String findSecurityReference(String name) { + String reference = null; try { referencesLock.readLock().lock(); - 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 9c753af..8796ed8 100644 --- a/java/org/apache/catalina/realm/RealmBase.java +++ b/java/org/apache/catalina/realm/RealmBase.java @@ -1060,7 +1060,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 3233929..b719efe 100644 --- a/test/org/apache/catalina/core/TestStandardWrapper.java +++ b/test/org/apache/catalina/core/TestStandardWrapper.java @@ -19,6 +19,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; @@ -190,6 +191,68 @@ 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.addServletMapping("/", "servlet"); + + MapRealm realm = new MapRealm(); + + /* 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", "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 8c130da..ec865ef 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -85,7 +85,11 @@ and a request does not map to any of the other deployed Contexts. Patch provided by Jop Zinkweg. (markt) </fix> - </changelog> + <fix> + <bug>63636</bug>: <code>Context.findRoleMapping()</code> never called + in <code>StandardWrapper.findSecurityReference()</code>. (michaelo) + </fix> + </changelog> </subsection> <subsection name="Coyote"> <changelog> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org