[java-identity-provider] branch main updated: IDP-1887 - Repurpose authn flow for alternative uses

Scott Cantor cantor.2 at osu.edu
Mon Dec 13 22:12:48 UTC 2021


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

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

View the commit online:
http://git.shibboleth.net/view/?p=java-identity-provider.git;a=commit;h=ce19b9030c49a8a6b59603ec9f575898f87abd6c

The following commit(s) were added to refs/heads/main by this push:
     new ce19b9030 IDP-1887 - Repurpose authn flow for alternative uses
ce19b9030 is described below

commit ce19b9030c49a8a6b59603ec9f575898f87abd6c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Dec 13 17:12:45 2021 -0500

    IDP-1887 - Repurpose authn flow for alternative uses
    
    https://shibboleth.atlassian.net/browse/IDP-1887
---
 .../authn/impl/PopulateAuthenticationContext.java  | 28 ++++++++++------------
 .../BaseMultiFactorAuthenticationContextTest.java  |  2 +-
 .../impl/PopulateAuthenticationContextTest.java    |  8 +++----
 .../testing/BaseAuthenticationContextTest.java     |  3 ++-
 .../net/shibboleth/idp/flows/authn/authn-flow.xml  | 26 ++++++++++++++++++--
 5 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/PopulateAuthenticationContext.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/PopulateAuthenticationContext.java
index e454ffc67..e061a16ad 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/PopulateAuthenticationContext.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/PopulateAuthenticationContext.java
@@ -34,6 +34,7 @@ import net.shibboleth.idp.authn.principal.PrincipalEvalPredicateFactoryRegistry;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
 import net.shibboleth.utilities.java.support.component.ComponentSupport;
 import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.logic.FunctionSupport;
 
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
@@ -60,8 +61,9 @@ public class PopulateAuthenticationContext extends AbstractAuthenticationAction
     /** All of the known flows in the system. */
     @Nonnull @NonnullElements private Collection<AuthenticationFlowDescriptor> availableFlows;
 
-    /** The flows to make available for possible use. */
-    @Nonnull @NonnullElements private Collection<AuthenticationFlowDescriptor> potentialFlows;
+    /** Lookup function for the flows to make available for possible use. */
+    @Nonnull
+    private Function<ProfileRequestContext,Collection<AuthenticationFlowDescriptor>> potentialFlowsLookupStrategy;
     
     /** Lookup function for the flow IDs to activate from within the available set. */
     @Nonnull private Function<ProfileRequestContext,Collection<String>> activeFlowsLookupStrategy;
@@ -75,7 +77,7 @@ public class PopulateAuthenticationContext extends AbstractAuthenticationAction
     /** Constructor. */
     public PopulateAuthenticationContext() {
         availableFlows = Collections.emptyList();
-        potentialFlows = Collections.emptyList();
+        potentialFlowsLookupStrategy = FunctionSupport.constant(Collections.emptyList());
         activeFlowsLookupStrategy = new AuthenticationFlowsLookupFunction();
     }
     
@@ -91,16 +93,17 @@ public class PopulateAuthenticationContext extends AbstractAuthenticationAction
     }
 
     /**
-     * Set the flows to make available for use (a subset of the available ones).
+     * Set the lookup strategy for the flows to make available for use (a subset of the available ones).
      * 
-     * @param flows the flows to make available for use
+     * @param strategy lookup strategy
      * 
-     * @since 3.3.0
+     * @since 4.2.0
      */
-    public void setPotentialFlows(@Nonnull @NonnullElements final Collection<AuthenticationFlowDescriptor> flows) {
+    public void setPotentialFlowsLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,Collection<AuthenticationFlowDescriptor>> strategy) {
         ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
         
-        potentialFlows = List.copyOf(Constraint.isNotNull(flows, "Flow collection cannot be null"));
+        potentialFlowsLookupStrategy = Constraint.isNotNull(strategy, "Potential flow lookup strategy cannot be null");
     }
     
     /**
@@ -157,11 +160,6 @@ public class PopulateAuthenticationContext extends AbstractAuthenticationAction
 
         if (evalRegistry != null) {
             authenticationContext.setPrincipalEvalPredicateFactoryRegistry(evalRegistry);
-            final RequestedPrincipalContext rpCtx =
-                    authenticationContext.getSubcontext(RequestedPrincipalContext.class);
-            if (rpCtx != null) {
-                rpCtx.setPrincipalEvalPredicateFactoryRegistry(evalRegistry);
-            }
         }
         
         if (fixedEventLookupStrategy != null) {
@@ -184,7 +182,7 @@ public class PopulateAuthenticationContext extends AbstractAuthenticationAction
         final Collection<String> activeFlows = activeFlowsLookupStrategy.apply(profileRequestContext);
 
         if (activeFlows != null && !activeFlows.isEmpty()) {
-            for (final AuthenticationFlowDescriptor desc : potentialFlows) {
+            for (final AuthenticationFlowDescriptor desc : potentialFlowsLookupStrategy.apply(profileRequestContext)) {
                 final String flowId = desc.getId().substring(desc.getId().indexOf('/') + 1);
                 if (activeFlows.contains(flowId)) {
                     if (authenticationContext.getAvailableFlows().containsKey(desc.getId())
@@ -199,7 +197,7 @@ public class PopulateAuthenticationContext extends AbstractAuthenticationAction
                 }
             }
         } else {
-            for (final AuthenticationFlowDescriptor desc : potentialFlows) {
+            for (final AuthenticationFlowDescriptor desc : potentialFlowsLookupStrategy.apply(profileRequestContext)) {
                 if (authenticationContext.getAvailableFlows().containsKey(desc.getId())
                         && desc.test(profileRequestContext)) {
                     authenticationContext.getPotentialFlows().put(desc.getId(), desc);
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/BaseMultiFactorAuthenticationContextTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/BaseMultiFactorAuthenticationContextTest.java
index f301c29c2..28442f509 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/BaseMultiFactorAuthenticationContextTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/BaseMultiFactorAuthenticationContextTest.java
@@ -85,7 +85,7 @@ public class BaseMultiFactorAuthenticationContextTest {
         
         final PopulateAuthenticationContext action = new PopulateAuthenticationContext();
         action.setAvailableFlows(authenticationFlows.values());
-        action.setPotentialFlows(Collections.singletonList(authenticationFlows.get("authn/MFA")));
+        action.setPotentialFlowsLookupStrategy(FunctionSupport.constant(Collections.singletonList(authenticationFlows.get("authn/MFA"))));
         action.initialize();
 
         action.execute(src);
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/PopulateAuthenticationContextTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/PopulateAuthenticationContextTest.java
index 7f94e664f..8498750a4 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/PopulateAuthenticationContextTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/PopulateAuthenticationContextTest.java
@@ -22,9 +22,9 @@ import net.shibboleth.idp.authn.context.AuthenticationContext;
 import net.shibboleth.idp.authn.impl.testing.BaseAuthenticationContextTest;
 import net.shibboleth.utilities.java.support.logic.FunctionSupport;
 
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.List;
 
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.opensaml.profile.testing.ActionTestingSupport;
@@ -49,7 +49,7 @@ final public class PopulateAuthenticationContextTest extends BaseAuthenticationC
         
         final PopulateAuthenticationContext action = new PopulateAuthenticationContext();
         action.setAvailableFlows(authenticationFlows);
-        action.setPotentialFlows(authenticationFlows);
+        action.setPotentialFlowsLookupStrategy(FunctionSupport.constant(authenticationFlows));
         action.initialize();
 
         action.execute(src);
@@ -78,7 +78,7 @@ final public class PopulateAuthenticationContextTest extends BaseAuthenticationC
         
         final AuthenticationFlowDescriptor unavailableFlow = new AuthenticationFlowDescriptor();
         unavailableFlow.setId("test4");
-        action.setPotentialFlows(Arrays.asList(authenticationFlows.get(0), unavailableFlow));
+        action.setPotentialFlowsLookupStrategy(FunctionSupport.constant(List.of(authenticationFlows.get(0), unavailableFlow)));
         action.initialize();
 
         action.execute(src);
@@ -108,7 +108,7 @@ final public class PopulateAuthenticationContextTest extends BaseAuthenticationC
         
         final PopulateAuthenticationContext action = new PopulateAuthenticationContext();
         action.setAvailableFlows(authenticationFlows);
-        action.setPotentialFlows(authenticationFlows);
+        action.setPotentialFlowsLookupStrategy(FunctionSupport.constant(authenticationFlows));
         action.setActiveFlowsLookupStrategy(
                 FunctionSupport.<ProfileRequestContext,Collection<String>>constant(Collections.singletonList("test2")));
         action.initialize();
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/testing/BaseAuthenticationContextTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/testing/BaseAuthenticationContextTest.java
index 8657ed2ac..0aa12199e 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/testing/BaseAuthenticationContextTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/testing/BaseAuthenticationContextTest.java
@@ -22,6 +22,7 @@ import net.shibboleth.idp.authn.context.AuthenticationContext;
 import net.shibboleth.idp.authn.impl.PopulateAuthenticationContext;
 import net.shibboleth.idp.profile.context.navigate.WebflowRequestContextProfileRequestContextLookup;
 import net.shibboleth.idp.profile.testing.RequestContextBuilder;
+import net.shibboleth.utilities.java.support.logic.FunctionSupport;
 
 import java.util.List;
 
@@ -54,7 +55,7 @@ public class BaseAuthenticationContextTest extends OpenSAMLInitBaseTestCase {
         
         final PopulateAuthenticationContext action = new PopulateAuthenticationContext();
         action.setAvailableFlows(authenticationFlows);
-        action.setPotentialFlows(authenticationFlows);
+        action.setPotentialFlowsLookupStrategy(FunctionSupport.constant(authenticationFlows));
         action.initialize();
 
         action.execute(src);
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/authn-flow.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/authn-flow.xml
index 2adc4830a..446ff804d 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/authn-flow.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/authn-flow.xml
@@ -9,9 +9,23 @@
     finalization of the processing such as updating a session, before returning control
     to the calling flow.
     -->
+
+    <!-- Allows use of standard global properties to be overridden. -->    
+    <input name="bypassSessionActions" type="boolean" />
+    <input name="potentialFlows" type="java.util.Collection" />
     
     <action-state id="AuthenticationSetup">
         <evaluate expression="PopulateAuthenticationContext" />
+        <evaluate expression="'proceed'" />
+        
+        <transition on="proceed" to="SessionSetup" />
+    </action-state>
+
+    <decision-state id="UseSessions1">
+        <if test="bypassSessionActions" then="FilterFlows" else="SessionSetup" />
+    </decision-state>
+
+    <action-state id="SessionSetup">
         <evaluate expression="PopulateSessionContext" />
         <evaluate expression="SetRPUIInformation" />
         <evaluate expression="'proceed'" />
@@ -88,9 +102,13 @@
     <!-- This runs a c14n step on the result of the authentication. -->
     <subflow-state id="CallSubjectCanonicalization" subflow="c14n">
         <input name="calledAsSubflow" value="true" />
-        <transition on="proceed" to="DetectIdentitySwitch" />
+        <transition on="proceed" to="UseSessions2" />
     </subflow-state>
 
+    <decision-state id="UseSessions2">
+        <if test="bypassSessionActions" then="FinalizeAuthentication" else="DetectIdentitySwitch" />
+    </decision-state>
+
     <!-- Handles an identity switch by dumping the old session. -->
     <action-state id="DetectIdentitySwitch">
         <evaluate expression="DetectIdentitySwitch" />
@@ -115,9 +133,13 @@
         <evaluate expression="FinalizeAuthentication" />
         <evaluate expression="'proceed'" />
         
-        <transition on="proceed" to="UpdateSessionWithAuthenticationResult" />
+        <transition on="proceed" to="UseSessions3" />
     </action-state>
     
+    <decision-state id="UseSessions3">
+        <if test="bypassSessionActions" then="proceed" else="UpdateSessionWithAuthenticationResult" />
+    </decision-state>
+    
     <!-- Finally, create/update the client session. -->
     <action-state id="UpdateSessionWithAuthenticationResult">
         <evaluate expression="UpdateSessionWithAuthenticationResult" />

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


More information about the commits mailing list