This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/main by this push:
new 7516c494dde Honour deny roles with the user roles map in
SimpleAuthorizingInterceptor (#3684)
7516c494dde is described below
commit 7516c494dde7bc5b0258de9fe22ede8160a8155a
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Thu Nov 5 12:12:31 2026 +0000
Honour deny roles with the user roles map in SimpleAuthorizingInterceptor
(#3684)
---
.../security/AbstractAuthorizingInInterceptor.java | 2 +-
.../security/SimpleAuthorizingInterceptor.java | 23 +++++++++
.../security/SimpleAuthorizingInterceptorTest.java | 60 ++++++++++++++++++++++
3 files changed, 84 insertions(+), 1 deletion(-)
diff --git
a/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
b/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
index b432258199c..ca6aafee858 100644
---
a/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
+++
b/core/src/main/java/org/apache/cxf/interceptor/security/AbstractAuthorizingInInterceptor.java
@@ -33,8 +33,8 @@ import org.apache.cxf.security.SecurityContext;
public abstract class AbstractAuthorizingInInterceptor extends
AbstractPhaseInterceptor<Message> {
+ protected static final String ALL_ROLES = "*";
private static final Logger LOG =
LogUtils.getL7dLogger(AbstractAuthorizingInInterceptor.class);
- private static final String ALL_ROLES = "*";
private boolean allowAnonymousUsers = true;
public AbstractAuthorizingInInterceptor() {
diff --git
a/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
b/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
index b4b591e388e..b73c62d68c2 100644
---
a/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
+++
b/core/src/main/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptor.java
@@ -52,6 +52,11 @@ public class SimpleAuthorizingInterceptor extends
AbstractAuthorizingInIntercept
@Override
protected boolean isUserInRole(SecurityContext sc, List<String> roles,
boolean deny) {
+ if (deny) {
+ // The user is authorized only if they have none of the deny
roles, whether from
+ // the security context or from the user roles map
+ return !hasAnyRole(sc, roles);
+ }
if (!checkConfiguredRolesOnly && !super.isUserInRole(sc, roles, deny))
{
return false;
}
@@ -71,6 +76,24 @@ public class SimpleAuthorizingInterceptor extends
AbstractAuthorizingInIntercept
return !checkConfiguredRolesOnly;
}
+ private boolean hasAnyRole(SecurityContext sc, List<String> roles) {
+ if (roles.size() == 1 && ALL_ROLES.equals(roles.get(0))) {
+ return true;
+ }
+ if (!checkConfiguredRolesOnly && super.isUserInRole(sc, roles, false))
{
+ return true;
+ }
+ List<String> userRoles =
userRolesMap.get(sc.getUserPrincipal().getName());
+ if (userRoles != null) {
+ for (String role : roles) {
+ if (userRoles.contains(role)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
protected String createMethodSig(Method method) {
StringBuilder b = new StringBuilder(method.getReturnType().getName());
b.append(' ').append(method.getName()).append('(');
diff --git
a/core/src/test/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptorTest.java
b/core/src/test/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptorTest.java
index a4252adeef3..544365cbafc 100644
---
a/core/src/test/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptorTest.java
+++
b/core/src/test/java/org/apache/cxf/interceptor/security/SimpleAuthorizingInterceptorTest.java
@@ -193,6 +193,66 @@ public class SimpleAuthorizingInterceptorTest {
in.handleMessage(message);
}
+ @Test(expected = AccessDeniedException.class)
+ public void testDenyWithDenyRolesFromUserRolesMap() {
+ SimpleAuthorizingInterceptor in =
createSimpleAuthorizingInterceptorWithDenyRoles("role1");
+ in.setUserRolesMap(Collections.singletonMap("testUser", "role1"));
+ in.handleMessage(message);
+ }
+
+ @Test(expected = AccessDeniedException.class)
+ public void testDenyWithDenyRolesFromSecurityContextAndUserRolesMap() {
+ SimpleAuthorizingInterceptor in =
createSimpleAuthorizingInterceptorWithDenyRoles("testRole");
+ in.setUserRolesMap(Collections.singletonMap("testUser", "role1"));
+ in.handleMessage(message);
+ }
+
+ @Test
+ public void testPermitWithDenyRolesAndUserRolesMap() {
+ SimpleAuthorizingInterceptor in =
createSimpleAuthorizingInterceptorWithDenyRoles("frogs");
+ in.setUserRolesMap(Collections.singletonMap("testUser", "role1"));
+ in.handleMessage(message);
+ }
+
+ @Test
+ public void testPermitWithDenyRolesUserNotInUserRolesMap() {
+ SimpleAuthorizingInterceptor in =
createSimpleAuthorizingInterceptorWithDenyRoles("frogs");
+ in.setUserRolesMap(Collections.singletonMap("otherUser", "role1"));
+ in.handleMessage(message);
+ }
+
+ @Test(expected = AccessDeniedException.class)
+ public void testDenyWithDenyRolesConfigurationOnly() {
+ SimpleAuthorizingInterceptor in =
createSimpleAuthorizingInterceptorWithDenyRoles("role1");
+ in.setCheckConfiguredRolesOnly(true);
+ in.setUserRolesMap(Collections.singletonMap("testUser", "role1"));
+ in.handleMessage(message);
+ }
+
+ @Test
+ public void testPermitWithDenyRolesConfigurationOnly() {
+ // Only the configured roles are checked, so the security context's
testRole is ignored
+ SimpleAuthorizingInterceptor in =
createSimpleAuthorizingInterceptorWithDenyRoles("testRole");
+ in.setCheckConfiguredRolesOnly(true);
+ in.setUserRolesMap(Collections.singletonMap("testUser", "role1"));
+ in.handleMessage(message);
+ }
+
+ @Test
+ public void testPermitWithDenyRolesConfigurationOnlyNoUserRolesMap() {
+ SimpleAuthorizingInterceptor in =
createSimpleAuthorizingInterceptorWithDenyRoles("frogs");
+ in.setCheckConfiguredRolesOnly(true);
+ in.handleMessage(message);
+ }
+
+ @Test(expected = AccessDeniedException.class)
+ public void testDenyAllConfigurationOnly() {
+ SimpleAuthorizingInterceptor in =
createSimpleAuthorizingInterceptorWithDenyRoles("*");
+ in.setCheckConfiguredRolesOnly(true);
+ in.setUserRolesMap(Collections.singletonMap("testUser", "role1"));
+ in.handleMessage(message);
+ }
+
@Test
public void testMethodSignatureRoles() throws Exception {
Method transfer = TestService.class.getMethod("transfer",
String.class, long.class);