From 1ee7b7d5b7a8f5d83c890475c4941e6c68efd146 Mon Sep 17 00:00:00 2001 From: sstremler Date: Fri, 31 Jan 2025 23:17:55 +0100 Subject: [PATCH] [CXF-9105] add synchronized to the principal iteration --- .../logging/event/DefaultLogEventMapper.java | 32 +++++++++++-------- .../logging/DefaultLogEventMapperTest.java | 29 +++++++++++++++++ 2 files changed, 48 insertions(+), 13 deletions(-) diff --git a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java index 2e77c8df649..4f9fefb77a5 100644 --- a/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java +++ b/rt/features/logging/src/main/java/org/apache/cxf/ext/logging/event/DefaultLogEventMapper.java @@ -19,6 +19,7 @@ package org.apache.cxf.ext.logging.event; import java.security.AccessController; +import java.security.Principal; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -109,7 +110,7 @@ public LogEvent map(final Message message, final Set sensitiveProtocolHe } private String getPrincipal(Message message) { - String principal = getJAASPrincipal(); + String principal = getConcatenatedJAASPrincipals(); if (principal != null) { return principal; } @@ -125,31 +126,36 @@ private String getPrincipal(Message message) { return null; } - private String getJAASPrincipal() { - StringBuilder principals = new StringBuilder(); - Iterator principalIt = getJAASPrincipals(); - while (principalIt.hasNext()) { - principals.append(principalIt.next()); - if (principalIt.hasNext()) { - principals.append(','); + private String getConcatenatedJAASPrincipals() { + StringBuilder principalsStringBuilder = new StringBuilder(); + Set principals = getJAASPrincipals(); + synchronized (principals) { + Iterator principalIt = principals.iterator(); + while (principalIt.hasNext()) { + principalsStringBuilder.append(principalIt.next()); + if (principalIt.hasNext()) { + principalsStringBuilder.append(','); + } } } - if (principals.length() == 0) { + + if (principalsStringBuilder.length() == 0) { return null; } - return principals.toString(); + + return principalsStringBuilder.toString(); } - private Iterator getJAASPrincipals() { + private Set getJAASPrincipals() { try { Subject subject = Subject.getSubject(AccessController.getContext()); return subject != null && subject.getPrincipals() != null - ? subject.getPrincipals().iterator() : Collections.emptyIterator(); + ? subject.getPrincipals() : Collections.emptySet(); } catch (UnsupportedOperationException e) { // JDK 23: The terminally deprecated method Subject.getSubject(AccessControlContext) has been re-specified // to throw UnsupportedOperationException if invoked when a Security Manager is not allowed. // see https://jdk.java.net/23/release-notes#JDK-8296244 - return Collections.emptyIterator(); + return Collections.emptySet(); } } diff --git a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/DefaultLogEventMapperTest.java b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/DefaultLogEventMapperTest.java index 9df839e6b68..f7c2a765c1f 100644 --- a/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/DefaultLogEventMapperTest.java +++ b/rt/features/logging/src/test/java/org/apache/cxf/ext/logging/DefaultLogEventMapperTest.java @@ -18,13 +18,20 @@ */ package org.apache.cxf.ext.logging; +import java.security.Principal; +import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import javax.security.auth.Subject; + +import org.apache.cxf.common.security.SimplePrincipal; import org.apache.cxf.ext.logging.event.DefaultLogEventMapper; import org.apache.cxf.ext.logging.event.EventType; import org.apache.cxf.ext.logging.event.LogEvent; @@ -147,4 +154,26 @@ public void testMap() { assertEquals("PUT[test]", event.getOperationName()); } + @Test + public void testMultiplePrincipalsReturnedByAccessControllerContext() { + DefaultLogEventMapper mapper = new DefaultLogEventMapper(); + Message message = new MessageImpl(); + message.put(Message.HTTP_REQUEST_METHOD, "GET"); + message.put(Message.REQUEST_URI, "test"); + Exchange exchange = new ExchangeImpl(); + message.setExchange(exchange); + + Set principals = IntStream.range(0, 3) + .mapToObj(i -> new SimplePrincipal("principal-" + i)) + .collect(Collectors.toSet()); + + Subject subject = new Subject(false, principals, Set.of(), Set.of()); + + LogEvent event = Subject.doAs(subject, (PrivilegedAction) () -> mapper.map(message)); + String[] splitPrincipals = event.getPrincipal().split(","); + Set expected = Set.of("principal-0", "principal-1", "principal-2"); + + assertEquals(expected, Arrays.stream(splitPrincipals).collect(Collectors.toSet())); + } + }