[java-identity-provider] branch main updated: IDP-2434 - Spring regression preventing override of login flow descs

Codeberg noreply at shibboleth.net
Mon Feb 16 14:05:38 UTC 2026


This is an automated email from the git hooks/post-receive script.

codeberg pushed a commit to branch main
in repository java-identity-provider.

View the commit online:
https://codeberg.org/Shibboleth/java-identity-provider/commit/968ea43a1970382e62f8e33caf75e95fc1d00045

The following commit(s) were added to refs/heads/main by this push:
     new 968ea43a1 IDP-2434 - Spring regression preventing override of login flow descs
968ea43a1 is described below

commit 968ea43a1970382e62f8e33caf75e95fc1d00045
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Feb 16 09:05:27 2026 -0500

    IDP-2434 - Spring regression preventing override of login flow descs
    
    https://shibboleth.atlassian.net/browse/IDP-2434
    
    Add unit test.
---
 .../idp/test/flows/AbstractFlowTest.java           |  5 +++
 .../idp/test/flows/AuthnFlowOverrideTest.java      | 52 ++++++++++++++++++++++
 .../net/shibboleth/idp/module/conf/global.xml      | 49 ++++++++++++++++++++
 3 files changed, 106 insertions(+)

diff --git a/idp-conf-impl/src/test/java/net/shibboleth/idp/test/flows/AbstractFlowTest.java b/idp-conf-impl/src/test/java/net/shibboleth/idp/test/flows/AbstractFlowTest.java
index 79d183368..c3998f213 100644
--- a/idp-conf-impl/src/test/java/net/shibboleth/idp/test/flows/AbstractFlowTest.java
+++ b/idp-conf-impl/src/test/java/net/shibboleth/idp/test/flows/AbstractFlowTest.java
@@ -69,6 +69,7 @@ import com.google.common.net.HttpHeaders;
 
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
+import net.shibboleth.idp.authn.impl.AuthenticationFlowDescriptorManager;
 import net.shibboleth.idp.spring.IdPPropertiesApplicationContextInitializer;
 import net.shibboleth.idp.test.PreferFileSystemApplicationContextInitializer;
 import net.shibboleth.idp.test.PreferFileSystemContextLoader;
@@ -183,6 +184,10 @@ public abstract class AbstractFlowTest extends AbstractTestNGSpringContextTests
 
     /** SP certificate wired via test/test-beans.xml. */
     @Autowired @Qualifier("test.sp.X509Certificate") protected X509CertificateFactoryBean certFactoryBean;
+    
+    /** Component manager for login flows to test for handling of bean overrides. */
+    @Autowired @Qualifier("shibboleth.AuthenticationFlowDescriptorManager")
+    AuthenticationFlowDescriptorManager authnFlowManager;
 
     /**
      * {@link HttpServletRequestResponseContext#clearCurrent()}
diff --git a/idp-conf-impl/src/test/java/net/shibboleth/idp/test/flows/AuthnFlowOverrideTest.java b/idp-conf-impl/src/test/java/net/shibboleth/idp/test/flows/AuthnFlowOverrideTest.java
new file mode 100644
index 000000000..f767984c4
--- /dev/null
+++ b/idp-conf-impl/src/test/java/net/shibboleth/idp/test/flows/AuthnFlowOverrideTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.shibboleth.idp.test.flows;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Unit test for regressions in fix for IDP-2434.
+ * 
+ * <p>Ensures legacy login flow descriptors are overriding system beans, but it notably
+ * cannot absolutely prevent a false positive because if the beans were to collide with
+ * the same ID, it is non-deterministic which one will be "seen" by the IdP.</p> 
+ */
+public class AuthnFlowOverrideTest extends AbstractFlowTest {
+
+    /**
+     * Interrogates flow descriptors to ensure overrides occurred.
+     */
+    @Test
+    public void testFlowDescriptors() {
+        final var descriptors = authnFlowManager.getComponents();
+        
+        var fd = descriptors.stream().filter(c -> { return "authn/SPNEGO".equals(c.getId()); }).findFirst();
+        Assert.assertTrue(fd.isPresent());
+        Assert.assertEquals(fd.get().getOrder(), 42);
+        Assert.assertEquals(fd.get().getFlowId(), "authn/SPNEGO-Test");
+
+        fd = descriptors.stream().filter(c -> { return "authn/X509".equals(c.getId()); }).findFirst();
+        Assert.assertTrue(fd.isPresent());
+        Assert.assertEquals(fd.get().getOrder(), 43);
+        Assert.assertEquals(fd.get().getFlowId(), "authn/X509-Test");
+
+        fd = descriptors.stream().filter(c -> { return "authn/External".equals(c.getId()); }).findFirst();
+        Assert.assertTrue(fd.isPresent());
+        Assert.assertEquals(fd.get().getOrder(), 1000);
+        Assert.assertEquals(fd.get().getFlowId(), "authn/External");
+    }
+    
+}
\ No newline at end of file
diff --git a/idp-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml b/idp-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml
index 98c13a1bc..d77bc6040 100644
--- a/idp-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml
+++ b/idp-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/global.xml
@@ -88,6 +88,55 @@
         <jdbc:script location="classpath:/test/test-jdbc.sql"/>
     </jdbc:initialize-database>
 
+    <!-- Used by unit test to detect any regressions in IDP-2434. -->
+    <util:list id="shibboleth.AvailableAuthenticationFlows">
+        <!-- This one uses the legacy id syntax for the component. -->
+        <bean id="authn/SPNEGO" parent="shibboleth.AuthenticationFlow"
+                p:flowId="authn/SPNEGO-Test"
+                p:order="42"
+                p:nonBrowserSupported="%{idp.authn.SPNEGO.nonBrowserSupported:false}"
+                p:passiveAuthenticationSupported="%{idp.authn.SPNEGO.passiveAuthenticationSupported:false}"
+                p:forcedAuthenticationSupported="%{idp.authn.SPNEGO.forcedAuthenticationSupported:false}"
+                p:proxyRestrictionsEnforced="%{idp.authn.SPNEGO.proxyRestrictionsEnforced:%{idp.authn.enforceProxyRestrictions:true}}"
+                p:proxyScopingEnforced="%{idp.authn.SPNEGO.proxyScopingEnforced:false}"
+                p:discoveryRequired="%{idp.authn.SPNEGO.discoveryRequired:false}"
+                p:lifetime="%{idp.authn.SPNEGO.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
+                p:inactivityTimeout="%{idp.authn.SPNEGO.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
+                p:reuseCondition-ref="#{'%{idp.authn.SPNEGO.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
+                p:activationCondition-ref="#{'%{idp.authn.SPNEGO.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+                p:resultLifetimeLookupStrategy-ref="#{'%{idp.authn.SPNEGO.lifetimeStrategy:NullDurationLookupStrategy}'.trim()}"
+                p:resultTimeoutLookupStrategy-ref="#{'%{idp.authn.SPNEGO.inactivityTimeoutStrategy:NullDurationLookupStrategy}'.trim()}"
+                p:subjectDecorator="#{getObject('%{idp.authn.SPNEGO.subjectDecorator:}'.trim())}">
+            <property name="supportedPrincipalsByString">
+                <bean parent="shibboleth.CommaDelimStringArray"
+                    c:_0="#{'%{idp.authn.SPNEGO.supportedPrincipals:}'.trim()}" />
+            </property>
+        </bean>
+    
+        <!-- This one uses the newer p:id syntax for the component. -->
+        <bean p:id="authn/X509" parent="shibboleth.AuthenticationFlow"
+                p:flowId="authn/X509-Test"
+                p:order="43"
+                p:nonBrowserSupported="%{idp.authn.X509.nonBrowserSupported:false}"
+                p:passiveAuthenticationSupported="%{idp.authn.X509.passiveAuthenticationSupported:false}"
+                p:forcedAuthenticationSupported="%{idp.authn.X509.forcedAuthenticationSupported:false}"
+                p:proxyRestrictionsEnforced="%{idp.authn.X509.proxyRestrictionsEnforced:%{idp.authn.enforceProxyRestrictions:true}}"
+                p:proxyScopingEnforced="%{idp.authn.X509.proxyScopingEnforced:false}"
+                p:discoveryRequired="%{idp.authn.X509.discoveryRequired:false}"
+                p:lifetime="%{idp.authn.X509.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
+                p:inactivityTimeout="%{idp.authn.X509.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
+                p:reuseCondition-ref="#{'%{idp.authn.X509.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
+                p:activationCondition-ref="#{'%{idp.authn.X509.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+                p:resultLifetimeLookupStrategy-ref="#{'%{idp.authn.X509.lifetimeStrategy:NullDurationLookupStrategy}'.trim()}"
+                p:resultTimeoutLookupStrategy-ref="#{'%{idp.authn.X509.inactivityTimeoutStrategy:NullDurationLookupStrategy}'.trim()}"
+                p:subjectDecorator="#{getObject('%{idp.authn.X509.subjectDecorator:}'.trim())}">
+            <property name="supportedPrincipalsByString">
+                <bean parent="shibboleth.CommaDelimStringArray"
+                    c:_0="#{'%{idp.authn.X509.supportedPrincipals:}'.trim()}" />
+            </property>
+        </bean>        
+    </util:list>
+
     <!--
     <bean id="testbed.MemcachedStorageService"
           class="org.opensaml.storage.impl.memcached.MemcachedStorageService"

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list