This is an automated email from the ASF dual-hosted git repository. coheigea pushed a commit to branch coheigea/deny in repository https://gitbox.apache.org/repos/asf/cxf.git
commit 0a9f678124ced4f85175dc072504435c55460d24 Author: Colm O hEigeartaigh <[email protected]> AuthorDate: Thu Nov 5 07:58:49 2026 +0000 Honour deny roles with the user roles map in SimpleAuthorizingInterceptor --- .../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);
