[java-identity-provider] branch main updated: IDP-1880 - Add admin properties for controlling authentication methods

Scott Cantor cantor.2 at osu.edu
Fri Nov 5 18:09:27 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=aec3855002138acefc04871c7399aaddee164d07

The following commit(s) were added to refs/heads/main by this push:
     new aec385500 IDP-1880 - Add admin properties for controlling authentication methods
aec385500 is described below

commit aec3855002138acefc04871c7399aaddee164d07
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Fri Nov 5 14:09:24 2021 -0400

    IDP-1880 - Add admin properties for controlling authentication methods
    
    https://shibboleth.atlassian.net/browse/IDP-1880
---
 .../admin/BasicAdministrativeFlowDescriptor.java   | 73 ++++++++++++++++++++++
 .../net/shibboleth/idp/conf/admin-system.xml       | 42 +++++++++++++
 .../src/main/resources/conf/admin/admin.properties |  9 +++
 3 files changed, 124 insertions(+)

diff --git a/idp-admin-api/src/main/java/net/shibboleth/idp/admin/BasicAdministrativeFlowDescriptor.java b/idp-admin-api/src/main/java/net/shibboleth/idp/admin/BasicAdministrativeFlowDescriptor.java
index 16d483d24..bba1069b3 100644
--- a/idp-admin-api/src/main/java/net/shibboleth/idp/admin/BasicAdministrativeFlowDescriptor.java
+++ b/idp-admin-api/src/main/java/net/shibboleth/idp/admin/BasicAdministrativeFlowDescriptor.java
@@ -18,6 +18,7 @@
 package net.shibboleth.idp.admin;
 
 import java.security.Principal;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -28,6 +29,7 @@ import java.util.function.Predicate;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import net.shibboleth.idp.authn.principal.PrincipalServiceManager;
 import net.shibboleth.idp.profile.config.AbstractProfileConfiguration;
 import net.shibboleth.idp.profile.config.SecurityConfiguration;
 import net.shibboleth.utilities.java.support.annotation.ParameterName;
@@ -37,6 +39,7 @@ import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
 import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
 import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
+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 net.shibboleth.utilities.java.support.primitive.LangBearingString;
@@ -91,6 +94,12 @@ public class BasicAdministrativeFlowDescriptor extends AbstractProfileConfigurat
     @Nonnull private Function<ProfileRequestContext,Collection<Principal>>
             defaultAuthenticationMethodsLookupStrategy;
 
+    /**
+     * Auhentication methods provided by delimited strings, for post-initialization override via
+     * {@link PrincipalServiceManager}.
+     */
+    @Nonnull private Function<ProfileRequestContext,Collection<String>> stringBasedPrincipalsLookupStrategy;
+    
     /** Filters the usable authentication flows. */
     @Nonnull private Function<ProfileRequestContext,Set<String>> authenticationFlowsLookupStrategy;
 
@@ -105,6 +114,9 @@ public class BasicAdministrativeFlowDescriptor extends AbstractProfileConfigurat
     
     /** Builder factory for XMLObjects needed in UIInfo emulation. */
     @Nonnull private final XMLObjectBuilderFactory builderFactory;
+
+    /** Access to principal services. */
+    @Nullable private PrincipalServiceManager principalServiceManager;
     
     /**
      * Constructor.
@@ -125,11 +137,23 @@ public class BasicAdministrativeFlowDescriptor extends AbstractProfileConfigurat
                 UIInfo.DEFAULT_ELEMENT_NAME)).buildObject();
         
         defaultAuthenticationMethodsLookupStrategy = FunctionSupport.constant(null);
+        stringBasedPrincipalsLookupStrategy = FunctionSupport.constant(null);
         authenticationFlowsLookupStrategy = FunctionSupport.constant(null);
         postAuthenticationFlowsLookupStrategy = FunctionSupport.constant(null);
         proxyCountLookupStrategy = FunctionSupport.constant(null);
     }
     
+    /**
+     * Sets a {@link PrincipalServiceManager} to use for string-based principal processing.
+     * 
+     * @param manager manager to set
+     * 
+     * @since 4.2.0
+     */
+    public void setPrincipalServiceManager(@Nullable final PrincipalServiceManager manager) {
+        principalServiceManager = manager;
+    }
+    
     /** {@inheritDoc} */
     @Nullable public String getLoggingId() {
         return loggingId;
@@ -351,10 +375,29 @@ public class BasicAdministrativeFlowDescriptor extends AbstractProfileConfigurat
     /** {@inheritDoc} */
     @Nonnull @NonnullElements @NotLive @Unmodifiable public List<Principal> getDefaultAuthenticationMethods(
             @Nullable final ProfileRequestContext profileRequestContext) {
+        
+        // Check for string-based representation first, then back off to native objects.
+        
+        if (principalServiceManager != null) {
+            final Collection<String> stringBasedPrincipals =
+                    stringBasedPrincipalsLookupStrategy.apply(profileRequestContext);
+            if (stringBasedPrincipals != null && !stringBasedPrincipals.isEmpty()) {
+                final List<Principal> principals = new ArrayList<>(stringBasedPrincipals.size());
+                stringBasedPrincipals.forEach(v -> {
+                    final Principal p = principalServiceManager.principalFromString(v);
+                    if (p != null) {
+                        principals.add(p);
+                    }
+                });
+                return List.copyOf(principals);
+            }
+        }
+        
         final Collection<Principal> methods = defaultAuthenticationMethodsLookupStrategy.apply(profileRequestContext);
         if (methods != null) {
             return List.copyOf(methods);
         }
+        
         return Collections.emptyList();
     }
     
@@ -382,6 +425,36 @@ public class BasicAdministrativeFlowDescriptor extends AbstractProfileConfigurat
         defaultAuthenticationMethodsLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
     }
 
+    /**
+     * Set the authentication methods to use, expressed as strings that will be
+     * converted to principals during initialization.
+     *
+     * @param methods default authentication methods to use, expressed as strings
+     * 
+     * @since 4.2.0
+     */
+    public void setDefaultAuthenticationMethodsByString(
+            @Nullable @NonnullElements final Collection<String> methods) {
+        if (methods != null) {
+            stringBasedPrincipalsLookupStrategy = FunctionSupport.constant(List.copyOf(methods));
+        } else {
+            stringBasedPrincipalsLookupStrategy = FunctionSupport.constant(null);
+        }
+    }
+    
+    /**
+     * Set a lookup strategy for the authentication methods to use, expressed as strings that will be
+     * converted to principals during initialization.
+     *
+     * @param strategy  lookup strategy
+     * 
+     * @since 4.2.0
+     */
+    public void setDefaultAuthenticationMethodsByStringLookupStrategy(
+            @Nonnull final Function<ProfileRequestContext,Collection<String>> strategy) {
+        stringBasedPrincipalsLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+    }
+    
     /** {@inheritDoc} */
     @Nonnull @NonnullElements @NotLive @Unmodifiable public Set<String> getAuthenticationFlows(
             @Nullable final ProfileRequestContext profileRequestContext) {
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml
index 5c6aecb41..3e52c1841 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/admin-system.xml
@@ -35,6 +35,10 @@
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.status.postAuthenticationFlows:}'.trim()}" />
         </property>
+        <property name="defaultAuthenticationMethodsByString">
+            <bean parent="shibboleth.CommaDelimStringArray"
+                c:_0="#{'%{idp.status.defaultAuthenticationMethods:}'.trim()}" />
+        </property>
     </bean>
 
     <bean parent="shibboleth.AdminFlow"
@@ -48,6 +52,10 @@
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.reload.postAuthenticationFlows:}'.trim()}" />
         </property>
+        <property name="defaultAuthenticationMethodsByString">
+            <bean parent="shibboleth.CommaDelimStringArray"
+                c:_0="#{'%{idp.reload.defaultAuthenticationMethods:}'.trim()}" />
+        </property>
     </bean>
 
     <bean parent="shibboleth.AdminFlow"
@@ -61,6 +69,10 @@
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.reload.postAuthenticationFlows:}'.trim()}" />
         </property>
+        <property name="defaultAuthenticationMethodsByString">
+            <bean parent="shibboleth.CommaDelimStringArray"
+                c:_0="#{'%{idp.reload.defaultAuthenticationMethods:}'.trim()}" />
+        </property>
     </bean>
 
     <bean parent="shibboleth.AdminFlow"
@@ -74,6 +86,10 @@
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.resolvertest.postAuthenticationFlows:}'.trim()}" />
         </property>
+        <property name="defaultAuthenticationMethodsByString">
+            <bean parent="shibboleth.CommaDelimStringArray"
+                c:_0="#{'%{idp.resolvertest.defaultAuthenticationMethods:}'.trim()}" />
+        </property>
     </bean>
 
     <bean parent="shibboleth.AdminFlow"
@@ -87,6 +103,10 @@
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.mdquery.postAuthenticationFlows:}'.trim()}" />
         </property>
+        <property name="defaultAuthenticationMethodsByString">
+            <bean parent="shibboleth.CommaDelimStringArray"
+                c:_0="#{'%{idp.mdquery.defaultAuthenticationMethods:}'.trim()}" />
+        </property>
     </bean>
 
     <bean parent="shibboleth.AdminFlow"
@@ -100,6 +120,10 @@
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.metrics.postAuthenticationFlows:}'.trim()}" />
         </property>
+        <property name="defaultAuthenticationMethodsByString">
+            <bean parent="shibboleth.CommaDelimStringArray"
+                c:_0="#{'%{idp.metrics.defaultAuthenticationMethods:}'.trim()}" />
+        </property>
     </bean>
 
     <bean parent="shibboleth.AdminFlow"
@@ -113,6 +137,10 @@
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.hello.postAuthenticationFlows:}'.trim()}" />
         </property>
+        <property name="defaultAuthenticationMethodsByString">
+            <bean parent="shibboleth.CommaDelimStringArray"
+                c:_0="#{'%{idp.hello.defaultAuthenticationMethods:}'.trim()}" />
+        </property>
     </bean>
 
     <bean parent="shibboleth.AdminFlow"
@@ -126,6 +154,10 @@
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.lockout.postAuthenticationFlows:}'.trim()}" />
         </property>
+        <property name="defaultAuthenticationMethodsByString">
+            <bean parent="shibboleth.CommaDelimStringArray"
+                c:_0="#{'%{idp.lockout.defaultAuthenticationMethods:}'.trim()}" />
+        </property>
     </bean>
 
     <bean parent="shibboleth.AdminFlow"
@@ -139,6 +171,10 @@
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.storage.postAuthenticationFlows:}'.trim()}" />
         </property>
+        <property name="defaultAuthenticationMethodsByString">
+            <bean parent="shibboleth.CommaDelimStringArray"
+                c:_0="#{'%{idp.storage.defaultAuthenticationMethods:}'.trim()}" />
+        </property>
     </bean>
 
     <bean parent="shibboleth.OneTimeAdminFlow"
@@ -152,16 +188,22 @@
             <bean parent="shibboleth.CommaDelimStringArray"
                 c:_0="#{'%{idp.unlock-keys.postAuthenticationFlows:}'.trim()}" />
         </property>
+        <property name="defaultAuthenticationMethodsByString">
+            <bean parent="shibboleth.CommaDelimStringArray"
+                c:_0="#{'%{idp.unlock-keys.defaultAuthenticationMethods:}'.trim()}" />
+        </property>
     </bean>
 
     <!-- Parent beans to default some of the flow boilerplate. -->
 
     <bean id="shibboleth.AdminFlow" abstract="true"
         class="net.shibboleth.idp.admin.BasicAdministrativeFlowDescriptor"
+        p:principalServiceManager-ref="shibboleth.PrincipalServiceManager"
         p:nonBrowserSupported="false" />
 
     <bean id="shibboleth.OneTimeAdminFlow" abstract="true"
         class="net.shibboleth.idp.admin.OneTimeAdministrativeFlowDescriptor"
+        p:principalServiceManager-ref="shibboleth.PrincipalServiceManager"
         p:nonBrowserSupported="false" />
 
     <!-- Function for returning custom access control policies for access to metrics. -->
diff --git a/idp-conf/src/main/resources/conf/admin/admin.properties b/idp-conf/src/main/resources/conf/admin/admin.properties
index 9831ba4b9..1e4f3a90e 100644
--- a/idp-conf/src/main/resources/conf/admin/admin.properties
+++ b/idp-conf/src/main/resources/conf/admin/admin.properties
@@ -4,6 +4,7 @@
 #idp.status.accessPolicy = AccessByIPAddress
 #idp.status.authenticated = false
 #idp.status.nonBrowserSupported = false
+#idp.status.defaultAuthenticationMethods =
 #idp.status.resolveAttributes = false
 #idp.status.postAuthenticationFlows =
 
@@ -11,6 +12,7 @@
 #idp.reload.accessPolicy = AccessByIPAddress
 #idp.reload.authenticated = false
 #idp.reload.nonBrowserSupported = false
+#idp.reload.defaultAuthenticationMethods =
 #idp.reload.resolveAttributes = false
 #idp.reload.postAuthenticationFlows =
 
@@ -18,6 +20,7 @@
 #idp.resolvertest.accessPolicy = AccessByIPAddress
 #idp.resolvertest.authenticated = false
 #idp.resolvertest.nonBrowserSupported = false
+#idp.resolvertest.defaultAuthenticationMethods =
 #idp.resolvertest.resolveAttributes = false
 #idp.resolvertest.postAuthenticationFlows =
 
@@ -25,12 +28,14 @@
 #idp.mdquery.accessPolicy = AccessByIPAddress
 #idp.mdquery.authenticated = false
 #idp.mdquery.nonBrowserSupported = false
+#idp.mdquery.defaultAuthenticationMethods =
 #idp.mdquery.resolveAttributes = false
 #idp.mdquery.postAuthenticationFlows =
 
 #idp.metrics.logging = Metrics
 #idp.metrics.authenticated = false
 #idp.metrics.nonBrowserSupported = false
+#idp.metrics.defaultAuthenticationMethods =
 #idp.metrics.resolveAttributes = false
 #idp.metrics.postAuthenticationFlows =
 # See admin/metrics.xml for other configuration
@@ -39,6 +44,7 @@
 #idp.hello.accessPolicy = AccessByAdminUser
 #idp.hello.authenticated = true
 #idp.hello.nonBrowserSupported = false
+#idp.hello.defaultAuthenticationMethods =
 #idp.hello.resolveAttributes = true
 #idp.hello.postAuthenticationFlows =
 
@@ -46,6 +52,7 @@
 #idp.lockout.accessPolicy = AccessDenied
 #idp.lockout.authenticated = false
 #idp.lockout.nonBrowserSupported = false
+#idp.lockout.defaultAuthenticationMethods =
 #idp.lockout.resolveAttributes = false
 #idp.lockout.postAuthenticationFlows =
 
@@ -53,6 +60,7 @@
 #idp.storage.accessPolicy = AccessDenied
 #idp.storage.authenticated = false
 #idp.storage.nonBrowserSupported = false
+#idp.storage.defaultAuthenticationMethods =
 #idp.storage.resolveAttributes = false
 #idp.storage.postAuthenticationFlows =
 
@@ -60,5 +68,6 @@
 #idp.unlock-keys.accessPolicy = AccessDenied
 #idp.unlock-keys.authenticated = true
 #idp.unlock-keys.nonBrowserSupported = false
+#idp.unlock-keys.defaultAuthenticationMethods =
 #idp.unlock-keys.resolveAttributes = false
 #idp.unlock-keys.postAuthenticationFlows =

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


More information about the commits mailing list