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 c003c55add9 Apply ClaimsAuthorizingInterceptor aliases set after the 
secured object (#3657)
c003c55add9 is described below

commit c003c55add97ceb199aeaed1cee8061a57e5037e
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Sun Nov 1 15:46:37 2026 +0000

    Apply ClaimsAuthorizingInterceptor aliases set after the secured object 
(#3657)
---
 .../interceptor/ClaimsAuthorizingInterceptor.java  | 29 ++++++++++++++-
 .../ClaimsAuthorizingInterceptorTest.java          | 43 ++++++++++++++++++++++
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git 
a/rt/security/src/main/java/org/apache/cxf/rt/security/claims/interceptor/ClaimsAuthorizingInterceptor.java
 
b/rt/security/src/main/java/org/apache/cxf/rt/security/claims/interceptor/ClaimsAuthorizingInterceptor.java
index e61755804ba..84ab8e45459 100644
--- 
a/rt/security/src/main/java/org/apache/cxf/rt/security/claims/interceptor/ClaimsAuthorizingInterceptor.java
+++ 
b/rt/security/src/main/java/org/apache/cxf/rt/security/claims/interceptor/ClaimsAuthorizingInterceptor.java
@@ -65,6 +65,9 @@ public class ClaimsAuthorizingInterceptor extends 
AbstractPhaseInterceptor<Messa
     private final Map<String, Set<String>> overriddenSignatures = new 
HashMap<>();
     private final Map<String, Set<String>> signaturesByName = new HashMap<>();
     private final Set<Class<?>> securedClasses = new HashSet<>();
+    // The classes passed to setSecuredObject, so their claims can be resolved 
again
+    // if the aliases change afterwards
+    private final List<Class<?>> securedObjectClasses = new ArrayList<>();
     private boolean annotationClaimsFound;
     private Map<String, String> nameAliases = Collections.emptyMap();
     private Map<String, String> formatAliases = Collections.emptyMap();
@@ -196,6 +199,7 @@ public class ClaimsAuthorizingInterceptor extends 
AbstractPhaseInterceptor<Messa
 
     public void setSecuredObject(Object object) {
         Class<?> cls = ClassHelper.getRealClass(object);
+        securedObjectClasses.add(cls);
         findClaims(cls);
         if (!annotationClaimsFound) {
             LOG.warning("The claims list is empty, the service object is not 
protected");
@@ -285,11 +289,32 @@ public class ClaimsAuthorizingInterceptor extends 
AbstractPhaseInterceptor<Messa
     }
 
     public void setNameAliases(Map<String, String> nameAliases) {
-        this.nameAliases = nameAliases;
+        this.nameAliases = nameAliases == null ? Collections.emptyMap() : 
nameAliases;
+        resolveSecuredObjectClaims();
     }
 
     public void setFormatAliases(Map<String, String> formatAliases) {
-        this.formatAliases = formatAliases;
+        this.formatAliases = formatAliases == null ? Collections.emptyMap() : 
formatAliases;
+        resolveSecuredObjectClaims();
+    }
+
+    /**
+     * The aliases are applied when the annotation claims are read, so read 
them again for any
+     * secured object which was set before the aliases. Otherwise the claims 
would keep the
+     * unresolved names, which never match, and a ClaimMode.LAX claim would 
always pass.
+     */
+    private void resolveSecuredObjectClaims() {
+        if (securedObjectClasses.isEmpty()) {
+            return;
+        }
+        declarationsBySignature.clear();
+        overriddenSignatures.clear();
+        signaturesByName.clear();
+        securedClasses.clear();
+        annotationClaimsFound = false;
+        for (Class<?> cls : securedObjectClasses) {
+            findClaims(cls);
+        }
     }
 
     private static final class ClaimsDeclaration {
diff --git 
a/rt/security/src/test/java/org/apache/cxf/rt/security/claims/interceptor/ClaimsAuthorizingInterceptorTest.java
 
b/rt/security/src/test/java/org/apache/cxf/rt/security/claims/interceptor/ClaimsAuthorizingInterceptorTest.java
index c75e9d63e0d..ef1155a4677 100644
--- 
a/rt/security/src/test/java/org/apache/cxf/rt/security/claims/interceptor/ClaimsAuthorizingInterceptorTest.java
+++ 
b/rt/security/src/test/java/org/apache/cxf/rt/security/claims/interceptor/ClaimsAuthorizingInterceptorTest.java
@@ -473,6 +473,39 @@ public class ClaimsAuthorizingInterceptorTest {
         assertDenied(in, prepareMessage(method, createDefaultClaim("user")));
     }
 
+    @Test
+    public void testAliasesSetAfterSecuredObject() throws Exception {
+        ClaimsAuthorizingInterceptor in = new ClaimsAuthorizingInterceptor();
+        in.setSecuredObject(new AliasService());
+        in.setNameAliases(Collections.singletonMap("authentication", 
"http://authentication";));
+        in.setFormatAliases(Collections.singletonMap("claims", 
"http://claims";));
+        Method lax = AliasService.class.getMethod("laxClaim");
+        Method strict = AliasService.class.getMethod("strictClaim");
+
+        in.handleMessage(prepareMessage(lax, 
createClaim("http://authentication";, "http://claims";, "password")));
+        assertDenied(in, prepareMessage(lax,
+            createClaim("http://authentication";, "http://claims";, 
"smartcard")));
+        in.handleMessage(prepareMessage(strict,
+            createClaim("http://authentication";, "http://claims";, 
"password")));
+        assertDenied(in, prepareMessage(strict,
+            createClaim("http://authentication";, "http://claims";, 
"smartcard")));
+    }
+
+    @Test
+    public void testAliasesReplacedAfterSecuredObject() throws Exception {
+        ClaimsAuthorizingInterceptor in = new ClaimsAuthorizingInterceptor();
+        in.setNameAliases(Collections.singletonMap("authentication", 
"http://old-authentication";));
+        in.setFormatAliases(Collections.singletonMap("claims", 
"http://claims";));
+        in.setSecuredObject(new AliasService());
+        in.setNameAliases(Collections.singletonMap("authentication", 
"http://authentication";));
+        Method lax = AliasService.class.getMethod("laxClaim");
+
+        assertDenied(in, prepareMessage(lax,
+            createClaim("http://authentication";, "http://claims";, 
"smartcard")));
+        in.handleMessage(prepareMessage(lax,
+            createClaim("http://old-authentication";, "http://claims";, 
"smartcard")));
+    }
+
     private static ClaimsAuthorizingInterceptor createInterceptor(Object 
service) {
         ClaimsAuthorizingInterceptor in = new ClaimsAuthorizingInterceptor();
         in.setSecuredObject(service);
@@ -640,6 +673,16 @@ public class ClaimsAuthorizingInterceptorTest {
 
         }
     }
+    public static class AliasService {
+        @Claim(name = "authentication", format = "claims", value = "password", 
mode = ClaimMode.LAX)
+        public void laxClaim() {
+        }
+
+        @Claim(name = "authentication", format = "claims", value = "password")
+        public void strictClaim() {
+        }
+    }
+
     public static class TestService2 {
         @SecureRole("admin")
         public void test() {

Reply via email to