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

rmaucher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new c6c231e0a0 Separate the Context role mapping from security-role-ref
c6c231e0a0 is described below

commit c6c231e0a04ab5722fbc5bd67273fbe4ddd3e751
Author: remm <[email protected]>
AuthorDate: Fri Jul 24 21:05:00 2026 +0200

    Separate the Context role mapping from security-role-ref
---
 java/org/apache/catalina/connector/Request.java        | 11 ++++++++++-
 java/org/apache/catalina/core/StandardWrapper.java     |  9 ---------
 java/org/apache/catalina/realm/RealmBase.java          |  8 +++++---
 test/org/apache/catalina/core/TestStandardWrapper.java | 12 ++++++++++++
 webapps/docs/changelog.xml                             |  4 ++++
 5 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/java/org/apache/catalina/connector/Request.java 
b/java/org/apache/catalina/connector/Request.java
index b563b1bc7d..4855e771df 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -2236,8 +2236,17 @@ public class Request implements HttpServletRequest {
             return false;
         }
 
+        // Check for a role alias defined in a <security-role-ref> element
+        Wrapper wrapper = getWrapper();
+        if (wrapper != null) {
+            String realRole = wrapper.findSecurityReference(role);
+            if (realRole != null) {
+                return realm.hasRole(wrapper, userPrincipal, realRole);
+            }
+        }
+
         // Check for a role defined directly as a <security-role>
-        return realm.hasRole(getWrapper(), userPrincipal, role);
+        return realm.hasRole(wrapper, userPrincipal, role);
     }
 
 
diff --git a/java/org/apache/catalina/core/StandardWrapper.java 
b/java/org/apache/catalina/core/StandardWrapper.java
index 4121a4e582..de2298992a 100644
--- a/java/org/apache/catalina/core/StandardWrapper.java
+++ b/java/org/apache/catalina/core/StandardWrapper.java
@@ -667,15 +667,6 @@ public class StandardWrapper extends ContainerBase 
implements ServletConfig, Wra
             referencesLock.readLock().unlock();
         }
 
-        // If not specified on the Wrapper, check the Context
-        if (getParent() instanceof Context context) {
-            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 3a6aa03803..55014f1987 100644
--- a/java/org/apache/catalina/realm/RealmBase.java
+++ b/java/org/apache/catalina/realm/RealmBase.java
@@ -902,9 +902,11 @@ public abstract class RealmBase extends LifecycleMBeanBase 
implements Realm {
     public boolean hasRole(Wrapper wrapper, Principal principal, String role) {
         // Check for a role alias
         if (wrapper != null) {
-            String realRole = wrapper.findSecurityReference(role);
-            if (realRole != null) {
-                role = realRole;
+            if (wrapper.getParent() instanceof Context context) {
+                String realRole = context.findRoleMapping(role);
+                if (realRole != null) {
+                    role = realRole;
+                }
             }
         }
 
diff --git a/test/org/apache/catalina/core/TestStandardWrapper.java 
b/test/org/apache/catalina/core/TestStandardWrapper.java
index 1c30e1600c..79a201f020 100644
--- a/test/org/apache/catalina/core/TestStandardWrapper.java
+++ b/test/org/apache/catalina/core/TestStandardWrapper.java
@@ -248,6 +248,8 @@ public class TestStandardWrapper extends TomcatBaseTest {
         ctx.addRoleMapping("testRole", "very-complex-role-name");
 
         Wrapper wrapper = Tomcat.addServlet(ctx, "servlet", 
RoleAllowServlet.class.getName());
+        wrapper.addSecurityReference("testSecurityRoleRef", 
"very-complex-role-name");
+        wrapper.addSecurityReference("testSecurityRoleRef2", "testRole");
         ctx.addServletMappingDecoded("/", "servlet");
 
         ctx.setLoginConfig(new LoginConfig("BASIC", null, null, null));
@@ -351,6 +353,8 @@ public class TestStandardWrapper extends TomcatBaseTest {
             TesterMapRealm realm = new TesterMapRealm();
             realm.addUser("testUser", "testPwd");
             realm.addUserRole("testUser", "testRole");
+            realm.addUserRole("testUser", "testSecurityRoleRef");
+            realm.addUserRole("testUser", "testSecurityRoleRef2");
             ctx.setRealm(realm);
 
             ctx.setLoginConfig(new LoginConfig("BASIC", null, null, null));
@@ -429,6 +433,14 @@ public class TestStandardWrapper extends TomcatBaseTest {
     @ServletSecurity(@HttpConstraint(rolesAllowed = "testRole"))
     public static class RoleAllowServlet extends TestServlet {
         private static final long serialVersionUID = 1L;
+
+        @Override
+        protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
+            if (!req.isUserInRole("testSecurityRoleRef") || 
!req.isUserInRole("testSecurityRoleRef2")) {
+                throw new ServletException("Non functional security-role-ref");
+            }
+            super.doGet(req, resp);
+        }
     }
 
     @ServletSecurity(@HttpConstraint(rolesAllowed = "otherRole"))
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 3bf0614603..83f9f5e5b4 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -278,6 +278,10 @@
         the client provided nonce count is at the upper boundary of the window
         (markt).
       </fix>
+      <update>
+        Separate the <code>Context</code> role mapping from the Servlet
+        specification <code>security-role-ref</code>. (remm)
+      </update>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to