[java-identity-provider] branch main updated: IDP-1716 - X509 flow within MFA and subject canonicalization

Scott Cantor cantor.2 at osu.edu
Mon Jan 25 21:05:38 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=080ef0dd6e1d35898940d4fc13a6c68f4620cd7e

The following commit(s) were added to refs/heads/main by this push:
       new  080ef0dd6 IDP-1716 - X509 flow within MFA and subject canonicalization
080ef0dd6 is described below

commit 080ef0dd6e1d35898940d4fc13a6c68f4620cd7e
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Jan 25 16:04:36 2021 -0500

    IDP-1716 - X509 flow within MFA and subject canonicalization
    
    https://issues.shibboleth.net/jira/browse/IDP-1716
    
    Add a generic hook to all flows for subject decoration.
---
 .../idp/authn/AbstractValidationAction.java        |  7 +++++
 .../idp/authn/AuthenticationFlowDescriptor.java    | 30 ++++++++++++++++++
 .../net/shibboleth/idp/conf/authn-system.xml       | 36 ++++++++++++++--------
 3 files changed, 61 insertions(+), 12 deletions(-)

diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractValidationAction.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractValidationAction.java
index 82a800cd0..fe5bcc392 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractValidationAction.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractValidationAction.java
@@ -24,6 +24,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -409,6 +410,12 @@ public abstract class AbstractValidationAction extends AbstractAuthenticationAct
                     authenticationContext.isResultCacheable() ? "will" : "will not");
         }
         
+        final BiConsumer<ProfileRequestContext,Subject> decorator =
+                authenticationContext.getAttemptedFlow().getSubjectDecorator();
+        if (decorator != null) {
+            decorator.accept(profileRequestContext, result.getSubject());
+        }
+        
         // Transfer the subject to a new c14n context.
         final SubjectCanonicalizationContext c14n = new SubjectCanonicalizationContext();
         c14n.setSubject(result.getSubject());
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptor.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptor.java
index 40cd60b45..cd362bef2 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptor.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptor.java
@@ -27,6 +27,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.BiConsumer;
 import java.util.function.Predicate;
 
 import javax.annotation.Nonnull;
@@ -127,6 +128,9 @@ public class AuthenticationFlowDescriptor extends AbstractIdentifiableInitializa
     
     /** Access to principal services. */
     @Nullable private PrincipalServiceManager principalServiceManager;
+    
+    /** Customizes subject prior to triggering subject canonicalization. */
+    @Nullable private BiConsumer<ProfileRequestContext,Subject> subjectDecorator;
 
     /** Constructor. */
     public AuthenticationFlowDescriptor() {
@@ -317,6 +321,32 @@ public class AuthenticationFlowDescriptor extends AbstractIdentifiableInitializa
                 Constraint.isNotNull(condition, "Predicate cannot be null"));
     }
 
+    /**
+     * Gets a subject decorating component called prior to completing authentication and passing
+     * control to subject canonicalization.
+     * 
+     * @return subject decorator
+     * 
+     * @since 4.1.0
+     */
+    @Nullable public BiConsumer<ProfileRequestContext,Subject> getSubjectDecorator() {
+        return subjectDecorator;
+    }
+    
+    /**
+     * Sets a subject decorating component called prior to completing authentication and passing
+     * control to subject canonicalization.
+     * 
+     * @param decorator
+     * 
+     * @since 4.1.0
+     */
+    public void setSubjectDecorator(@Nullable final BiConsumer<ProfileRequestContext,Subject> decorator) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        
+        subjectDecorator = decorator;
+    }    
+
     /**
      * Get the maximum amount of time, since first usage, a flow should be considered active. A null
      * indicates that there is no upper limit on the lifetime on an active flow.
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/authn-system.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/authn-system.xml
index b99fff872..b6cf1c7b2 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/authn-system.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/authn-system.xml
@@ -53,7 +53,8 @@
             p:lifetime="%{idp.authn.Password.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
             p:inactivityTimeout="%{idp.authn.Password.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
             p:reuseCondition-ref="#{'%{idp.authn.Password.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
-            p:activationCondition-ref="#{'%{idp.authn.Password.activationCondition:shibboleth.Conditions.TRUE}'.trim()}">
+            p:activationCondition-ref="#{'%{idp.authn.Password.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.Password.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.Password.supportedPrincipals:}'.trim()}" />
@@ -71,7 +72,8 @@
             p:lifetime="%{idp.authn.IPAddress.lifetime:PT60S}"
             p:inactivityTimeout="%{idp.authn.IPAddress.inactivityTimeout:PT60S}"
             p:reuseCondition-ref="#{'%{idp.authn.IPAddress.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
-            p:activationCondition-ref="#{'%{idp.authn.IPAddress.activationCondition:shibboleth.Conditions.TRUE}'.trim()}">
+            p:activationCondition-ref="#{'%{idp.authn.IPAddress.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.IPAddress.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.IPAddress.supportedPrincipals:}'.trim()}" />
@@ -89,7 +91,8 @@
             p:lifetime="%{idp.authn.Function.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
             p:inactivityTimeout="%{idp.authn.Function.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
             p:reuseCondition-ref="#{'%{idp.authn.Function.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
-            p:activationCondition-ref="#{'%{idp.authn.Function.activationCondition:shibboleth.Conditions.TRUE}'.trim()}">
+            p:activationCondition-ref="#{'%{idp.authn.Function.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.Function.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.Function.supportedPrincipals:}'.trim()}" />
@@ -107,7 +110,8 @@
             p:lifetime="%{idp.authn.External.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
             p:inactivityTimeout="%{idp.authn.External.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
             p:reuseCondition-ref="#{'%{idp.authn.External.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
-            p:activationCondition-ref="#{'%{idp.authn.External.activationCondition:shibboleth.Conditions.TRUE}'.trim()}">
+            p:activationCondition-ref="#{'%{idp.authn.External.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.External.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.External.supportedPrincipals:}'.trim()}" />
@@ -125,7 +129,8 @@
             p:lifetime="%{idp.authn.RemoteUser.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
             p:inactivityTimeout="%{idp.authn.RemoteUser.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
             p:reuseCondition-ref="#{'%{idp.authn.RemoteUser.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
-            p:activationCondition-ref="#{'%{idp.authn.RemoteUser.activationCondition:shibboleth.Conditions.TRUE}'.trim()}">
+            p:activationCondition-ref="#{'%{idp.authn.RemoteUser.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.RemoteUser.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.RemoteUser.supportedPrincipals:}'.trim()}" />
@@ -143,7 +148,8 @@
             p:lifetime="%{idp.authn.RemoteUserInternal.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
             p:inactivityTimeout="%{idp.authn.RemoteUserInternal.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
             p:reuseCondition-ref="#{'%{idp.authn.RemoteUserInternal.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
-            p:activationCondition-ref="#{'%{idp.authn.RemoteUserInternal.activationCondition:shibboleth.Conditions.TRUE}'.trim()}">
+            p:activationCondition-ref="#{'%{idp.authn.RemoteUserInternal.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.RemoteUserInternal.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.RemoteUserInternal.supportedPrincipals:}'.trim()}" />
@@ -161,7 +167,8 @@
             p:lifetime="%{idp.authn.SAML.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
             p:inactivityTimeout="%{idp.authn.SAML.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
             p:reuseCondition-ref="#{'%{idp.authn.SAML.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
-            p:activationCondition-ref="#{'%{idp.authn.SAML.activationCondition:shibboleth.Conditions.TRUE}'.trim()}">
+            p:activationCondition-ref="#{'%{idp.authn.SAML.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.SAML.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.SAML.supportedPrincipals:}'.trim()}" />
@@ -179,7 +186,8 @@
             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:activationCondition-ref="#{'%{idp.authn.SPNEGO.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.SPNEGO.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.SPNEGO.supportedPrincipals:}'.trim()}" />
@@ -197,7 +205,8 @@
             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:activationCondition-ref="#{'%{idp.authn.X509.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.X509.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.X509.supportedPrincipals:}'.trim()}" />
@@ -215,7 +224,8 @@
             p:lifetime="%{idp.authn.X509Internal.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
             p:inactivityTimeout="%{idp.authn.X509Internal.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
             p:reuseCondition-ref="#{'%{idp.authn.X509Internal.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
-            p:activationCondition-ref="#{'%{idp.authn.X509Internal.activationCondition:shibboleth.Conditions.TRUE}'.trim()}">
+            p:activationCondition-ref="#{'%{idp.authn.X509Internal.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.X509Internal.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.X509Internal.supportedPrincipals:}'.trim()}" />
@@ -233,7 +243,8 @@
             p:lifetime="%{idp.authn.Duo.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
             p:inactivityTimeout="%{idp.authn.Duo.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
             p:reuseCondition-ref="#{'%{idp.authn.Duo.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
-            p:activationCondition-ref="#{'%{idp.authn.Duo.activationCondition:shibboleth.Conditions.TRUE}'.trim()}">
+            p:activationCondition-ref="#{'%{idp.authn.Duo.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.Duo.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.Duo.supportedPrincipals:}'.trim()}" />
@@ -251,7 +262,8 @@
             p:lifetime="%{idp.authn.MFA.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
             p:inactivityTimeout="%{idp.authn.MFA.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
             p:reuseCondition-ref="#{'%{idp.authn.MFA.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
-            p:activationCondition-ref="#{'%{idp.authn.MFA.activationCondition:shibboleth.Conditions.TRUE}'.trim()}">
+            p:activationCondition-ref="#{'%{idp.authn.MFA.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
+            p:subjectDecorator="#{getObject('%{idp.authn.MFA.subjectDecorator}'.trim())}">
         <property name="supportedPrincipalsByString">
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.authn.MFA.supportedPrincipals:}'.trim()}" />

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


More information about the commits mailing list