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() {