You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rz...@apache.org on 2026/04/23 13:50:46 UTC
(tomee) 08/23: security/cdi: dedupe mechanism definitions collected in ProcessBean
This is an automated email from the ASF dual-hosted git repository.
rzo1 pushed a commit to branch security-4.0
in repository https://gitbox.apache.org/repos/asf/tomee.git
commit 14e5173ff75900003d1e40a8126ea32f6853dfe3
Author: Richard Zowalla <rz...@apache.org>
AuthorDate: Mon Apr 20 20:32:14 2026 +0200
security/cdi: dedupe mechanism definitions collected in ProcessBean
ProcessBean can fire more than once for the same annotated type
(e.g. when CDI synthesises observer/interceptor beans on it), so
List.addAll accumulated duplicate @*AuthenticationMechanismDefinition
instances. After c723b38920 started registering one bean per
collected definition, this produced multiple beans with identical
qualifier sets and AmbiguousResolutionException on startup -- the
tomee-security servlet tests failed to deploy.
Switch the four *MechanismDefinitions collections to LinkedHashSet
(annotations are value-equal) and snapshot them to ordered lists at
AfterBeanDiscovery time so the indexed bean-id scheme still works.
Also update OpenIdAuthenticationMechanismUnitTest to set the
definition through the supplier hook rather than reflecting into a
field that no longer exists.
---
.../tomee/security/cdi/TomEESecurityExtension.java | 23 ++++++++++++++++++----
.../cdi/OpenIdAuthenticationMechanismUnitTest.java | 2 +-
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/TomEESecurityExtension.java b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/TomEESecurityExtension.java
index 00656eaa5b..79358d428b 100644
--- a/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/TomEESecurityExtension.java
+++ b/tomee/tomee-security/src/main/java/org/apache/tomee/security/cdi/TomEESecurityExtension.java
@@ -60,15 +60,20 @@ import jakarta.security.enterprise.identitystore.LdapIdentityStoreDefinition;
import java.lang.annotation.Annotation;
import java.util.ArrayList;
+import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
public class TomEESecurityExtension implements Extension {
- private final List<BasicAuthenticationMechanismDefinition> basicMechanismDefinitions = new ArrayList<>();
- private final List<FormAuthenticationMechanismDefinition> formMechanismDefinitions = new ArrayList<>();
- private final List<CustomFormAuthenticationMechanismDefinition> customMechanismDefinitions = new ArrayList<>();
- private final List<OpenIdAuthenticationMechanismDefinition> oidcMechanismDefinitions = new ArrayList<>();
+ // LinkedHashSet: ProcessBean fires for each bean *and* any derived observer/interceptor beans on the
+ // same class, so List.addAll would otherwise duplicate identical annotation instances and cause
+ // AmbiguousResolutionException when multiple beans are registered with the same qualifier set.
+ private final Set<BasicAuthenticationMechanismDefinition> basicMechanismDefinitions = new LinkedHashSet<>();
+ private final Set<FormAuthenticationMechanismDefinition> formMechanismDefinitions = new LinkedHashSet<>();
+ private final Set<CustomFormAuthenticationMechanismDefinition> customMechanismDefinitions = new LinkedHashSet<>();
+ private final Set<OpenIdAuthenticationMechanismDefinition> oidcMechanismDefinitions = new LinkedHashSet<>();
private final AtomicReference<Annotated> tomcatUserStore = new AtomicReference<>();
private final AtomicReference<Annotated> databaseStore = new AtomicReference<>();
@@ -129,6 +134,16 @@ public class TomEESecurityExtension implements Extension {
@Observes final AfterBeanDiscovery afterBeanDiscovery,
final BeanManager beanManager) {
+ // Snapshot definition sets as ordered lists so the registration loops can use index-based IDs.
+ final List<BasicAuthenticationMechanismDefinition> basicMechanismDefinitions =
+ new ArrayList<>(this.basicMechanismDefinitions);
+ final List<FormAuthenticationMechanismDefinition> formMechanismDefinitions =
+ new ArrayList<>(this.formMechanismDefinitions);
+ final List<CustomFormAuthenticationMechanismDefinition> customMechanismDefinitions =
+ new ArrayList<>(this.customMechanismDefinitions);
+ final List<OpenIdAuthenticationMechanismDefinition> oidcMechanismDefinitions =
+ new ArrayList<>(this.oidcMechanismDefinitions);
+
if (tomcatUserStore.get() != null) {
afterBeanDiscovery
.addBean()
diff --git a/tomee/tomee-security/src/test/java/org/apache/tomee/security/cdi/OpenIdAuthenticationMechanismUnitTest.java b/tomee/tomee-security/src/test/java/org/apache/tomee/security/cdi/OpenIdAuthenticationMechanismUnitTest.java
index 2c3df3989e..0626cf0ed9 100644
--- a/tomee/tomee-security/src/test/java/org/apache/tomee/security/cdi/OpenIdAuthenticationMechanismUnitTest.java
+++ b/tomee/tomee-security/src/test/java/org/apache/tomee/security/cdi/OpenIdAuthenticationMechanismUnitTest.java
@@ -59,7 +59,7 @@ public class OpenIdAuthenticationMechanismUnitTest {
identityStoreHandler = mock(IdentityStoreHandler.class);
storageHandler = new SimpleStorageHandler();
- Reflections.set(authenticationMechanism, "definition", definition);
+ authenticationMechanism.setDefinitionSupplier(() -> definition);
Reflections.set(authenticationMechanism, "identityStoreHandler", identityStoreHandler);
Reflections.set(authenticationMechanism, "openIdContext", new TomEEOpenIdContext());
Reflections.set(authenticationMechanism, "storageHandler", storageHandler);