[java-identity-provider] branch main updated: Convert password flow to module with property-driven configuration.

Scott Cantor cantor.2 at osu.edu
Tue Sep 15 18:22:15 UTC 2020


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=d540326f6210e039ab24d570ef5144ade8b6477e

The following commit(s) were added to refs/heads/main by this push:
       new  d540326f6 Convert password flow to module with property-driven configuration.
d540326f6 is described below

commit d540326f6210e039ab24d570ef5144ade8b6477e
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Sep 15 14:22:06 2020 -0400

    Convert password flow to module with property-driven configuration.
---
 ...bstractUsernamePasswordCredentialValidator.java | 19 +++--
 .../idp/authn/impl/JAASCredentialValidator.java    | 82 +++++++++++++++----
 .../authn/impl/KerberosCredentialValidator.java    |  2 +-
 .../idp/authn/impl/ValidateCredentials.java        |  9 ++-
 .../authn/impl/JAASCredentialValidatorTest.java    | 38 ++++-----
 .../shibboleth/idp/module/authn/impl/Password.java | 41 ++++++++++
 .../services/net.shibboleth.idp.module.IdPModule   |  1 +
 .../idp/flows/authn/password-authn-beans.xml       | 91 +++++++++++++---------
 .../authn/remoteuser-internal-authn-beans.xml      |  6 +-
 .../idp/module/authn/impl/module.properties        | 13 ++++
 .../module}/conf/authn/password-authn-config.xml   | 30 +------
 .../shibboleth/idp/module}/views/login-error.vm    |  0
 .../net/shibboleth/idp/module}/views/login.vm      |  0
 .../idp/module}/views/spnego-unavailable.vm        |  0
 .../src/main/resources/conf/authn/authn.properties | 37 ++++++++-
 .../resources/conf/authn/jaas-authn-config.xml     | 25 ------
 idp-conf/src/main/resources/conf/authn/jaas.config | 11 ---
 .../resources/conf/authn/krb5-authn-config.xml     | 29 -------
 .../resources/conf/authn/ldap-authn-config.xml     | 32 --------
 .../resources/conf/authn/jaas-authn-config.xml     | 25 ------
 .../resources/conf/authn/password-authn-config.xml | 30 +------
 21 files changed, 254 insertions(+), 267 deletions(-)

diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractUsernamePasswordCredentialValidator.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractUsernamePasswordCredentialValidator.java
index 953f7736f..54c0be397 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractUsernamePasswordCredentialValidator.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractUsernamePasswordCredentialValidator.java
@@ -176,15 +176,18 @@ public abstract class AbstractUsernamePasswordCredentialValidator extends Abstra
      * 
      * @param newTransforms collection of replacement transforms
      */
-    public void setTransforms(@Nonnull @NonnullElements final Collection<Pair<String, String>> newTransforms) {
+    public void setTransforms(@Nullable @NonnullElements final Collection<Pair<String, String>> newTransforms) {
         ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
-        Constraint.isNotNull(newTransforms, "Transforms collection cannot be null");
-        
-        transforms = new ArrayList<>();
-        for (final Pair<String,String> p : newTransforms) {
-            final Pattern pattern = Pattern.compile(StringSupport.trimOrNull(p.getFirst()));
-            transforms.add(new Pair<>(pattern, Constraint.isNotNull(
-                    StringSupport.trimOrNull(p.getSecond()), "Replacement expression cannot be null")));
+
+        if (newTransforms != null) {
+            transforms = new ArrayList<>();
+            for (final Pair<String,String> p : newTransforms) {
+                final Pattern pattern = Pattern.compile(StringSupport.trimOrNull(p.getFirst()));
+                transforms.add(new Pair<>(pattern, Constraint.isNotNull(
+                        StringSupport.trimOrNull(p.getSecond()), "Replacement expression cannot be null")));
+            }
+        } else {
+            transforms = Collections.emptyList();
         }
     }
 
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/JAASCredentialValidator.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/JAASCredentialValidator.java
index d96633fca..53e9e8d4f 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/JAASCredentialValidator.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/JAASCredentialValidator.java
@@ -17,8 +17,11 @@
 
 package net.shibboleth.idp.authn.impl;
 
+import java.io.IOException;
+import java.net.URI;
 import java.security.NoSuchAlgorithmException;
 import java.security.Principal;
+import java.security.URIParameter;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -45,12 +48,14 @@ import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElemen
 import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
 import net.shibboleth.utilities.java.support.annotation.constraint.ThreadSafeAfterInit;
 import net.shibboleth.utilities.java.support.collection.Pair;
+import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 import net.shibboleth.utilities.java.support.component.ComponentSupport;
 import net.shibboleth.utilities.java.support.primitive.StringSupport;
 
 import org.opensaml.profile.context.ProfileRequestContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.core.io.Resource;
 
 /**
  * A password validator that authenticates against JAAS.
@@ -68,12 +73,18 @@ public class JAASCredentialValidator extends AbstractUsernamePasswordCredentialV
     
     /** Type of JAAS Configuration to instantiate. */
     @Nullable private String loginConfigType;
-    
+
+    /** JAAS configuration resource. */
+    @Nullable private Resource loginConfigResource;
+
     /** Type-specific configuration parameters. */
     @Nullable private Configuration.Parameters loginConfigParameters;
     
+    /** Holder for simple configurations defined by name. */
+    @Nullable @NonnullElements private Collection<String> loginConfigNames;
+    
     /** Application name(s) in JAAS configuration to use. */
-    @Nonnull private Collection<Pair<String,Subject>> loginConfigurations;
+    @Nonnull @NonnullElements private Collection<Pair<String,Subject>> loginConfigurations;
     
     /** Strategy function to dynamically derive the login config(s) to use. */
     @Nullable private Function<ProfileRequestContext,Collection<Pair<String,Subject>>> loginConfigStrategy;
@@ -81,7 +92,8 @@ public class JAASCredentialValidator extends AbstractUsernamePasswordCredentialV
     /** Constructor. */
     public JAASCredentialValidator() {
         // For compatibility with V2.
-        loginConfigurations = Collections.singletonList(new Pair<String,Subject>("ShibUserPassAuth", null));
+        loginConfigNames = Collections.singletonList("ShibUserPassAuth");
+        loginConfigurations = Collections.emptyList();
     }
     
     /**
@@ -114,14 +126,31 @@ public class JAASCredentialValidator extends AbstractUsernamePasswordCredentialV
     }
 
     /**
-     * Set the type-specific parameters of the JAAS {@link Configuration} to use.
+     * Set a URI to use as a JAAS configuration parameter.
      * 
-     * @param params the JAAS configuration parameters to use
+     * @param uri the JAAS configuration URI parameters to use
      */
-    public void setLoginConfigParameters(@Nullable final Configuration.Parameters params) {
+    public void setLoginConfigParameters(@Nullable final URI uri) {
         ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
         
-        loginConfigParameters = params;
+        if (uri != null) {
+            loginConfigParameters = new URIParameter(uri);
+        } else {
+            loginConfigParameters = null;
+        }
+    }
+
+    /**
+     * Set a login configuration resource to use.
+     * 
+     * @param resource resource to use
+     * 
+     * @since 4.1.0
+     */
+    public void setLoginConfigResource(@Nullable final Resource resource) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        
+        loginConfigResource = resource;
     }
 
     /**
@@ -139,7 +168,7 @@ public class JAASCredentialValidator extends AbstractUsernamePasswordCredentialV
                 final String trimmed = StringSupport.trimOrNull(config.getFirst());
                 if (trimmed != null) {
                     if (config.getSecond() == null || config.getSecond().isEmpty()) {
-                        loginConfigurations.add(new Pair<String,Subject>(trimmed, null));
+                        loginConfigurations.add(new Pair<>(trimmed, null));
                     } else {
                         final Subject subject = new Subject();
                         subject.getPrincipals().addAll(config.getSecond());
@@ -158,15 +187,7 @@ public class JAASCredentialValidator extends AbstractUsernamePasswordCredentialV
     public void setLoginConfigNames(@Nullable @NonnullElements final Collection<String> names) {
         ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
 
-        if (names != null) {
-            loginConfigurations = new ArrayList<>(names.size());
-            for (final String name : names) {
-                final String trimmed = StringSupport.trimOrNull(name);
-                if (trimmed != null) {
-                    loginConfigurations.add(new Pair<String,Subject>(trimmed,null));
-                }
-            }
-        }
+        loginConfigNames = StringSupport.normalizeStringCollection(names);
     }
     
     /**
@@ -181,6 +202,33 @@ public class JAASCredentialValidator extends AbstractUsernamePasswordCredentialV
         loginConfigStrategy = strategy;
     }
     
+    /** {@inheritDoc} */
+    @Override
+    protected void doInitialize() throws ComponentInitializationException {
+        super.doInitialize();
+        
+        // Deferred initialization of config by just names.
+        if (loginConfigStrategy == null && loginConfigurations.isEmpty()) {
+            loginConfigurations = new ArrayList<>(loginConfigNames.size());
+            for (final String name : loginConfigNames) {
+                loginConfigurations.add(new Pair<>(name, null));
+            }
+        }
+        
+        if (loginConfigType != null && loginConfigParameters == null) {
+            if (loginConfigResource != null) {
+                try {
+                    loginConfigParameters = new URIParameter(loginConfigResource.getURI());
+                } catch (final IOException e) {
+                    throw new ComponentInitializationException("Unable to login configuration resource into URI", e);
+                }
+            } else {
+                throw new ComponentInitializationException("No login configuration resource or parameters supplied");
+            }
+        }
+        
+    }
+    
     /** {@inheritDoc} */
     @Override
     @Nullable protected Subject doValidate(@Nonnull final ProfileRequestContext profileRequestContext,
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/KerberosCredentialValidator.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/KerberosCredentialValidator.java
index e20b23402..ec7d45342 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/KerberosCredentialValidator.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/KerberosCredentialValidator.java
@@ -147,7 +147,7 @@ public class KerberosCredentialValidator extends AbstractUsernamePasswordCredent
     public void setKeytabPath(@Nullable final String path) {
         ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
         
-        keytabPath = path;
+        keytabPath = StringSupport.trimOrNull(path);
     }
     
     /** {@inheritDoc} */
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateCredentials.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateCredentials.java
index f0fce76c9..2a56ec04d 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateCredentials.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateCredentials.java
@@ -39,7 +39,6 @@ import net.shibboleth.idp.authn.context.UsernamePasswordContext;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
 import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
 import net.shibboleth.utilities.java.support.component.ComponentSupport;
-import net.shibboleth.utilities.java.support.logic.Constraint;
 
 import org.opensaml.profile.action.ActionSupport;
 import org.opensaml.profile.action.EventIds;
@@ -108,10 +107,14 @@ public class ValidateCredentials extends AbstractValidationAction implements War
      * 
      * @param validators validators to use
      */
-    public void setValidators(@Nonnull @NonnullElements final List<CredentialValidator> validators) {
+    public void setValidators(@Nullable @NonnullElements final List<CredentialValidator> validators) {
         ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
         
-        credentialValidators = List.copyOf(Constraint.isNotNull(validators, "Validators list cannot be null"));
+        if (validators != null) {
+            credentialValidators = List.copyOf(validators);
+        } else {
+            credentialValidators = Collections.emptyList();
+        }
     }
     
     /**
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/JAASCredentialValidatorTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/JAASCredentialValidatorTest.java
index d2df62f37..6056d2df7 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/JAASCredentialValidatorTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/JAASCredentialValidatorTest.java
@@ -20,7 +20,6 @@ package net.shibboleth.idp.authn.impl;
 import java.io.File;
 import java.io.IOException;
 import java.security.Principal;
-import java.security.URIParameter;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -42,6 +41,7 @@ import net.shibboleth.idp.profile.ActionTestingSupport;
 import net.shibboleth.utilities.java.support.collection.Pair;
 import net.shibboleth.utilities.java.support.net.URISupport;
 
+import org.springframework.core.io.ClassPathResource;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.webflow.execution.Event;
 import org.testng.Assert;
@@ -59,7 +59,9 @@ import com.unboundid.ldap.sdk.LDAPException;
 public class JAASCredentialValidatorTest extends BaseAuthenticationContextTest {
 
     private static final String DATA_PATH = "src/test/resources/net/shibboleth/idp/authn/impl/";
-    
+
+    private static final String DATA_CLASSPATH = "/net/shibboleth/idp/authn/impl/";
+
     private JAASCredentialValidator validator;
     
     private ValidateCredentials action;
@@ -162,8 +164,8 @@ public class JAASCredentialValidatorTest extends BaseAuthenticationContextTest {
         ac.setAttemptedFlow(authenticationFlows.get(0));
         validator.setLoginConfigNames(Collections.singletonList("ShibBadAuth"));
         validator.setLoginConfigType("JavaLoginConfig");
-        validator.setLoginConfigParameters(new URIParameter(URISupport.fileURIFromAbsolutePath(getCurrentDir()
-                + '/' + DATA_PATH + "jaas.config")));
+        validator.setLoginConfigParameters(URISupport.fileURIFromAbsolutePath(getCurrentDir()
+                + '/' + DATA_PATH + "jaas.config"));
         validator.initialize();
         
         action.initialize();
@@ -191,10 +193,10 @@ public class JAASCredentialValidatorTest extends BaseAuthenticationContextTest {
         rpc.setRequestedPrincipals(Collections.<Principal>singletonList(new TestPrincipal("test1")));
 
         validator.setLoginConfigurations(Collections.singletonList(new Pair<String,Collection<Principal>>("ShibUserPassAuth",
-                Collections.<Principal>singletonList(new TestPrincipal("test2")))));
+                Collections.singletonList(new TestPrincipal("test2")))));
         validator.setLoginConfigType("JavaLoginConfig");
-        validator.setLoginConfigParameters(new URIParameter(URISupport.fileURIFromAbsolutePath(getCurrentDir()
-                + '/' + DATA_PATH + "jaas.config")));
+        validator.setLoginConfigParameters(URISupport.fileURIFromAbsolutePath(getCurrentDir()
+                + '/' + DATA_PATH + "jaas.config"));
         validator.initialize();
         
         action.initialize();
@@ -231,8 +233,7 @@ public class JAASCredentialValidatorTest extends BaseAuthenticationContextTest {
         final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
         ac.setAttemptedFlow(authenticationFlows.get(0));
         validator.setLoginConfigType("JavaLoginConfig");
-        validator.setLoginConfigParameters(new URIParameter(URISupport.fileURIFromAbsolutePath(getCurrentDir()
-                + '/' + DATA_PATH + "jaas.config")));
+        validator.setLoginConfigResource(new ClassPathResource(DATA_CLASSPATH + "jaas.config"));
         
         validator.initialize();
         action.initialize();
@@ -254,8 +255,7 @@ public class JAASCredentialValidatorTest extends BaseAuthenticationContextTest {
         final AuthenticationContext ac = prc.getSubcontext(AuthenticationContext.class);
         ac.setAttemptedFlow(authenticationFlows.get(0));
         validator.setLoginConfigType("JavaLoginConfig");
-        validator.setLoginConfigParameters(new URIParameter(URISupport.fileURIFromAbsolutePath(getCurrentDir()
-                + '/' + DATA_PATH + "jaas.config")));
+        validator.setLoginConfigResource(new ClassPathResource(DATA_CLASSPATH + "jaas.config"));
         validator.initialize();
         
         action.initialize();
@@ -278,8 +278,8 @@ public class JAASCredentialValidatorTest extends BaseAuthenticationContextTest {
         ac.setAttemptedFlow(authenticationFlows.get(0));
 
         validator.setLoginConfigType("JavaLoginConfig");
-        validator.setLoginConfigParameters(new URIParameter(URISupport.fileURIFromAbsolutePath(getCurrentDir()
-                + '/' + DATA_PATH + "jaas.config")));
+        validator.setLoginConfigParameters(URISupport.fileURIFromAbsolutePath(getCurrentDir()
+                + '/' + DATA_PATH + "jaas.config"));
         validator.initialize();
         
         action.initialize();
@@ -302,8 +302,7 @@ public class JAASCredentialValidatorTest extends BaseAuthenticationContextTest {
         ac.setAttemptedFlow(authenticationFlows.get(0));
 
         validator.setLoginConfigType("JavaLoginConfig");
-        validator.setLoginConfigParameters(new URIParameter(URISupport.fileURIFromAbsolutePath(getCurrentDir()
-                + '/' + DATA_PATH + "jaas.config")));
+        validator.setLoginConfigResource(new ClassPathResource(DATA_CLASSPATH + "jaas.config"));
         validator.initialize();
         
         action.initialize();
@@ -334,8 +333,7 @@ public class JAASCredentialValidatorTest extends BaseAuthenticationContextTest {
         validator.setLoginConfigurations(Collections.singletonList(new Pair<String,Collection<Principal>>("ShibUserPassAuth",
                 Collections.<Principal>singletonList(new TestPrincipal("test1")))));
         validator.setLoginConfigType("JavaLoginConfig");
-        validator.setLoginConfigParameters(new URIParameter(URISupport.fileURIFromAbsolutePath(getCurrentDir()
-                + '/' + DATA_PATH + "jaas.config")));
+        validator.setLoginConfigResource(new ClassPathResource(DATA_CLASSPATH + "jaas.config"));
         validator.initialize();
         
         action.initialize();
@@ -361,8 +359,7 @@ public class JAASCredentialValidatorTest extends BaseAuthenticationContextTest {
 
         validator.setLoginConfigNames(Arrays.asList("ShibBadAuth", "ShibUserPassAuth"));
         validator.setLoginConfigType("JavaLoginConfig");
-        validator.setLoginConfigParameters(new URIParameter(URISupport.fileURIFromAbsolutePath(getCurrentDir()
-                + '/' + DATA_PATH + "jaas.config")));
+        validator.setLoginConfigResource(new ClassPathResource(DATA_CLASSPATH + "jaas.config"));
         validator.initialize();
         
         action.initialize();
@@ -385,8 +382,7 @@ public class JAASCredentialValidatorTest extends BaseAuthenticationContextTest {
         ac.setAttemptedFlow(authenticationFlows.get(0));
 
         validator.setLoginConfigType("JavaLoginConfig");
-        validator.setLoginConfigParameters(new URIParameter(URISupport.fileURIFromAbsolutePath(getCurrentDir()
-                + '/' + DATA_PATH + "jaas.config")));
+        validator.setLoginConfigResource(new ClassPathResource(DATA_CLASSPATH + "jaas.config"));
         validator.setMatchExpression(Pattern.compile(".+_THE_.+"));
         validator.initialize();
         
diff --git a/idp-conf-impl/src/main/java/net/shibboleth/idp/module/authn/impl/Password.java b/idp-conf-impl/src/main/java/net/shibboleth/idp/module/authn/impl/Password.java
new file mode 100644
index 000000000..c0261e14d
--- /dev/null
+++ b/idp-conf-impl/src/main/java/net/shibboleth/idp/module/authn/impl/Password.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the University Corporation for Advanced Internet Development,
+ * Inc. (UCAID) under one or more contributor license agreements.  See the
+ * NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The UCAID licenses this file to You 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.module.authn.impl;
+
+import java.io.IOException;
+
+import net.shibboleth.idp.module.IdPModule;
+import net.shibboleth.idp.module.ModuleException;
+import net.shibboleth.idp.module.PropertyDrivenIdPModule;
+
+/**
+ * {@link IdPModule} implementation.
+ */
+public final class Password extends PropertyDrivenIdPModule {
+
+    /**
+     * Constructor.
+     *  
+     * @throws ModuleException on error
+     * @throws IOException on error
+     */
+    public Password() throws IOException, ModuleException {
+        super(Password.class);
+    }
+
+}
\ No newline at end of file
diff --git a/idp-conf-impl/src/main/resources/META-INF/services/net.shibboleth.idp.module.IdPModule b/idp-conf-impl/src/main/resources/META-INF/services/net.shibboleth.idp.module.IdPModule
index 06926e514..74c4bf885 100644
--- a/idp-conf-impl/src/main/resources/META-INF/services/net.shibboleth.idp.module.IdPModule
+++ b/idp-conf-impl/src/main/resources/META-INF/services/net.shibboleth.idp.module.IdPModule
@@ -3,6 +3,7 @@ net.shibboleth.idp.module.authn.impl.External
 net.shibboleth.idp.module.authn.impl.Function
 net.shibboleth.idp.module.authn.impl.IPAddress
 net.shibboleth.idp.module.authn.impl.MFA
+net.shibboleth.idp.module.authn.impl.Password
 net.shibboleth.idp.module.authn.impl.RemoteUser
 net.shibboleth.idp.module.authn.impl.RemoteUserInternal
 net.shibboleth.idp.module.authn.impl.SPNEGO
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-beans.xml
index 0c8ca9b49..bf38d3830 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/password-authn-beans.xml
@@ -18,7 +18,41 @@
     <bean class="net.shibboleth.ext.spring.config.IdentifiableBeanPostProcessor" />
     <bean class="net.shibboleth.idp.profile.impl.ProfileActionBeanPostProcessor" />
 
-    <import resource="%{idp.home}/conf/authn/password-authn-config.xml" />
+    <bean id="shibboleth.X509ResourceCredentialConfig"
+        class="net.shibboleth.idp.authn.impl.X509ResourceCredentialConfig" abstract="true" /> 
+    <bean id="shibboleth.KeystoreResourceCredentialConfig"
+        class="net.shibboleth.idp.authn.impl.KeystoreResourceCredentialConfig" abstract="true" /> 
+
+    <!-- Legacy approach, needed to allow override via config. -->
+    <bean id="shibboleth.authn.Password.addDefaultPrincipals" class="java.lang.Boolean" factory-method="valueOf"
+        c:_0="%{idp.authn.Password.addDefaultPrincipals:true}" />
+    <bean id="shibboleth.authn.Password.RemoveAfterValidation" class="java.lang.Boolean" factory-method="valueOf"
+        c:_0="%{idp.authn.Password.removeAfterValidation:true}" />
+
+    <!-- Formerly public beans in ldap-authn-config.xml, overrideable via import. -->
+    <bean id="shibboleth.authn.LDAP.returnAttributes" parent="shibboleth.CommaDelimStringArray">
+        <constructor-arg type="java.lang.String" value="%{idp.authn.LDAP.returnAttributes:1.1}" />
+    </bean>
+    <bean id="shibboleth.authn.LDAP.trustCertificates" parent="shibboleth.X509ResourceCredentialConfig"
+        p:trustCertificates="%{idp.authn.LDAP.trustCertificates:undefined}" />
+    <bean id="shibboleth.authn.LDAP.truststore" parent="shibboleth.KeystoreResourceCredentialConfig"
+        p:truststore="%{idp.authn.LDAP.trustStore:undefined}" />
+    <bean id="shibboleth.authn.LDAP.authenticator" parent="shibboleth.LDAPAuthenticationFactory" lazy-init="true" />
+
+    <!-- Formerly public beans in jaas-authn-config.xml, overrideable via import. -->
+    <bean id="shibboleth.authn.JAAS.LoginConfigNames" parent="shibboleth.CommaDelimStringArray"
+        c:_0="#{'%{idp.authn.JAAS.loginConfigNames:ShibUserPassAuth}'.trim()}" />
+
+    <!-- Default message map. -->
+    <util:map id="shibboleth.authn.Password.ClassifiedMessageMap">
+        <entry key="RequestUnsupported">
+            <list>
+                <value>RequestUnsupported</value>
+            </list>
+        </entry>
+    </util:map>
+
+    <import resource="conditional:%{idp.home}/conf/authn/password-authn-config.xml" />
 
     <bean id="ExtractUsernamePasswordFromBasicAuth"
         class="net.shibboleth.idp.authn.impl.ExtractUsernamePasswordFromBasicAuth" scope="prototype"
@@ -32,9 +66,9 @@
     <bean id="ExtractUsernamePasswordFromFormRequest"
         class="net.shibboleth.idp.authn.impl.ExtractUsernamePasswordFromFormRequest" scope="prototype"
         p:httpServletRequest-ref="shibboleth.HttpServletRequest"
-        p:usernameFieldName-ref="shibboleth.authn.Password.UsernameFieldName"
-        p:passwordFieldName-ref="shibboleth.authn.Password.PasswordFieldName"
-        p:SSOBypassFieldName-ref="shibboleth.authn.Password.SSOBypassFieldName" />
+        p:usernameFieldName="#{getObject('shibboleth.authn.Password.UsernameFieldName') ?: '%{idp.authn.Password.usernameFieldName:j_username}'.trim()}"
+        p:passwordFieldName="#{getObject('shibboleth.authn.Password.PasswordFieldName') ?: '%{idp.authn.Password.passwordFieldName:j_password}'.trim()}"
+        p:SSOBypassFieldName="#{getObject('shibboleth.authn.Password.SSOBypassFieldName') ?: '%{idp.authn.Password.ssoBypassFieldName:donotcache}'.trim()}" />
         
     <bean id="PopulateSubjectCanonicalizationContext"
         class="net.shibboleth.idp.authn.impl.PopulateSubjectCanonicalizationContext" scope="prototype"
@@ -42,30 +76,26 @@
     
     <bean id="DefaultCleanupHook" class="net.shibboleth.idp.authn.impl.ValidateCredentials.UsernamePasswordCleanupHook" />
     
-    <!-- New action bean that uses CredentialValidator chains. -->    
+    <!-- New action bean that uses CredentialValidator chains. -->
     <bean id="ValidateCredentials"
         class="net.shibboleth.idp.authn.impl.ValidateCredentials" scope="prototype"
-        p:requireAll="#{getObject('shibboleth.authn.Password.RequireAll') ?: false}"
+        p:requireAll="#{getObject('shibboleth.authn.Password.RequireAll') ?: %{idp.authn.Password.requireAll:false}}"
         p:validators="#{getObject('shibboleth.authn.Password.Validators') ?: getObject('ValidateUsernamePassword')}"
-        p:addDefaultPrincipals="#{getObject('shibboleth.authn.Password.addDefaultPrincipals') ?:
-            (getObject('shibboleth.authn.Password.PrincipalOverride') == null
-                or getObject('shibboleth.authn.Password.PrincipalOverride').isEmpty())}"
+        p:addDefaultPrincipals-ref="shibboleth.authn.Password.addDefaultPrincipals"
         p:supportedPrincipals="#{getObject('shibboleth.authn.Password.PrincipalOverride')}"
-        p:classifiedMessages-ref="shibboleth.authn.Password.ClassifiedMessageMap"
+        p:classifiedMessages="#{getObject('shibboleth.authn.Password.ClassifiedMessageMap')}"
         p:resultCachingPredicate="#{getObject('shibboleth.authn.Password.resultCachingPredicate')}"
-        p:cleanupHook="#{getObject('shibboleth.authn.Password.RemoveAfterValidation') != null and
-                            getObject('shibboleth.authn.Password.RemoveAfterValidation') == true
-                                ? getObject('DefaultCleanupHook') : null}"
+        p:cleanupHook="#{getObject('shibboleth.authn.Password.RemoveAfterValidation') == true ? getObject('DefaultCleanupHook') : null}"
         p:lockoutManager="#{getObject('shibboleth.authn.Password.AccountLockoutManager')}" />
     
     <!-- New parent bean for defining validators. -->
     
     <bean id="shibboleth.CredentialValidator" abstract="true"
-        p:savePasswordToCredentialSet="#{getObject('shibboleth.authn.Password.RetainAsPrivateCredential') ?: false}"
-        p:lowercase-ref="shibboleth.authn.Password.Lowercase"
-        p:uppercase-ref="shibboleth.authn.Password.Uppercase"
-        p:trim-ref="shibboleth.authn.Password.Trim"
-        p:transforms-ref="shibboleth.authn.Password.Transforms"        
+        p:savePasswordToCredentialSet="#{getObject('shibboleth.authn.Password.RetainAsPrivateCredential') ?: %{idp.authn.Password.retainAsPrivateCredential:false}}"
+        p:lowercase="#{getObject('shibboleth.authn.Password.Lowercase') ?: %{idp.authn.Password.lowercase:false}}"
+        p:uppercase="#{getObject('shibboleth.authn.Password.Uppercase') ?: %{idp.authn.Password.uppercase:false}}"
+        p:trim="#{getObject('shibboleth.authn.Password.Trim') ?: %{idp.authn.Password.trim:true}}"
+        p:transforms="#{getObject('shibboleth.authn.Password.Transforms')}"
         p:matchExpression="#{getObject('shibboleth.authn.Password.matchExpression')}" />
 
     <!-- New validator(s) that didn't exist in prior versions. -->
@@ -85,15 +115,11 @@
             class="net.shibboleth.idp.authn.impl.JAASCredentialValidator"
             p:id="jaas"
             p:loginConfigStrategy="#{getObject('shibboleth.authn.JAAS.LoginConfigStrategy')}"
-            p:loginConfigNames="#{getObject('shibboleth.authn.JAAS.LoginConfigNames')}"
+            p:loginConfigNames-ref="shibboleth.authn.JAAS.LoginConfigNames"
             p:loginConfigurations="#{getObject('shibboleth.authn.JAAS.LoginConfigurations')}"
-            p:loginConfigType="JavaLoginConfig">
-        <property name="loginConfigParameters">
-            <bean class="java.security.URIParameter">
-                <constructor-arg ref="shibboleth.authn.JAAS.JAASConfigURI" />
-            </bean>
-        </property>
-    </bean>
+            p:loginConfigType="JavaLoginConfig"
+            p:loginConfigResource="'%{idp.authn.JAAS.loginConfig:%{idp.home}/conf/authn/jaas.config}'.trim()"
+            p:loginConfigParameters="#{getObject('shibboleth.authn.JAAS.JAASConfigURI')}" />
 
     <bean id="shibboleth.authn.JAAS.LoginConfigStrategy.RelyingPartyMap" abstract="true"
         class="net.shibboleth.idp.authn.impl.RelyingPartyMapJAASLoginConfigStrategy" />
@@ -101,10 +127,10 @@
     <bean id="ValidateUsernamePasswordAgainstKerberos" parent="shibboleth.CredentialValidator" lazy-init="true"
         class="net.shibboleth.idp.authn.impl.KerberosCredentialValidator"
         p:id="krb5"
-        p:refreshKrb5Config-ref="shibboleth.authn.Krb5.RefreshConfig"
-        p:preserveTicket-ref="shibboleth.authn.Krb5.PreserveTicket"
-        p:servicePrincipal="#{getObject('shibboleth.authn.Krb5.ServicePrincipal')}"
-        p:keytabPath="#{getObject('shibboleth.authn.Krb5.Keytab')}" />
+        p:refreshKrb5Config="#{getObject('shibboleth.authn.Krb5.RefreshConfig') ?: %{idp.authn.Krb5.refreshConfig:false}}"
+        p:preserveTicket="#{getObject('shibboleth.authn.Krb5.PreserveTicket') ?: %{idp.authn.Krb5.preserveTicket:false}}"
+        p:servicePrincipal="#{getObject('shibboleth.authn.Krb5.ServicePrincipal') ?: %{idp.authn.Krb5.servicePrincipal:}}"
+        p:keytabPath="#{getObject('shibboleth.authn.Krb5.Keytab') ?: %{idp.authn.Krb5.keytab:}}" />
 
     <bean id="ValidateUsernamePasswordAgainstLDAP" parent="shibboleth.CredentialValidator" lazy-init="true"
         class="net.shibboleth.idp.authn.impl.LDAPCredentialValidator"
@@ -150,10 +176,5 @@
         p:activeDirectory="%{idp.authn.LDAP.activeDirectory:false}"
         p:freeIPA="%{idp.authn.LDAP.freeIPADirectory:false}"
         p:EDirectory="%{idp.authn.LDAP.eDirectory:false}" />
-            
-    <bean id="shibboleth.X509ResourceCredentialConfig"
-        class="net.shibboleth.idp.authn.impl.X509ResourceCredentialConfig" abstract="true" /> 
-    <bean id="shibboleth.KeystoreResourceCredentialConfig"
-        class="net.shibboleth.idp.authn.impl.KeystoreResourceCredentialConfig" abstract="true" /> 
 
 </beans>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-internal-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-internal-authn-beans.xml
index 72ba468fc..a6b5e181b 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-internal-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/remoteuser-internal-authn-beans.xml
@@ -44,9 +44,9 @@
         p:checkRemoteUser="#{getObject('shibboleth.authn.RemoteUser.checkRemoteUser') ?: %{idp.authn.RemoteUserInternal.checkRemoteUser:true}}"
         p:checkHeaders="#{getObject('shibboleth.authn.RemoteUser.checkHeaders')}"
         p:checkAttributes="#{getObject('shibboleth.authn.RemoteUser.checkAttributes')}"
-        p:lowercase="#{getObject('shibboleth.authn.RemoteUser.Lowercase') ?: %{idp.authn.RemoteUserInternal.Lowercase:false}}"
-        p:uppercase="#{getObject('shibboleth.authn.RemoteUser.Uppercase') ?: %{idp.authn.RemoteUserInternal.Uppercase:false}}"
-        p:trim="#{getObject('shibboleth.authn.RemoteUser.Trim') ?: %{idp.authn.RemoteUserInternal.Trim:true}}"
+        p:lowercase="#{getObject('shibboleth.authn.RemoteUser.Lowercase') ?: %{idp.authn.RemoteUserInternal.lowercase:false}}"
+        p:uppercase="#{getObject('shibboleth.authn.RemoteUser.Uppercase') ?: %{idp.authn.RemoteUserInternal.uppercase:false}}"
+        p:trim="#{getObject('shibboleth.authn.RemoteUser.Trim') ?: %{idp.authn.RemoteUserInternal.trim:true}}"
         p:transforms="#{getObject('shibboleth.authn.RemoteUser.Transforms')}" />
 
     <bean id="PropertyDrivenAllowList" parent="shibboleth.CommaDelimStringArray"
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/authn/impl/module.properties b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/authn/impl/module.properties
index dccf93bc7..4604226a7 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/authn/impl/module.properties
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/authn/impl/module.properties
@@ -6,6 +6,7 @@ net.shibboleth.idp.module.authn.impl.External = idp.authn.External
 net.shibboleth.idp.module.authn.impl.Function = idp.authn.Function
 net.shibboleth.idp.module.authn.impl.IPAddress = idp.authn.IPAddress
 net.shibboleth.idp.module.authn.impl.MFA = idp.authn.MFA
+net.shibboleth.idp.module.authn.impl.Password = idp.authn.Password
 net.shibboleth.idp.module.authn.impl.RemoteUser = idp.authn.RemoteUser
 net.shibboleth.idp.module.authn.impl.RemoteUserInternal = idp.authn.RemoteUserInternal
 net.shibboleth.idp.module.authn.impl.SPNEGO = idp.authn.SPNEGO
@@ -46,6 +47,16 @@ idp.authn.MFA.url = https://wiki.shibboleth.net/confluence/display/IDP4/MultiFac
 idp.authn.MFA.1.src = /net/shibboleth/idp/module/conf/authn/mfa-authn-config.xml
 idp.authn.MFA.1.dest = conf/authn/mfa-authn-config.xml
 
+idp.authn.Password.name = Password Authentication
+idp.authn.Password.desc = Login flow for pluggable password-based authentication
+idp.authn.Password.url = https://wiki.shibboleth.net/confluence/display/IDP4/PasswordAuthnConfiguration
+idp.authn.Password.1.src = /net/shibboleth/idp/module/conf/authn/password-authn-config.xml
+idp.authn.Password.1.dest = conf/authn/password-authn-config.xml
+idp.authn.Password.2.src = /net/shibboleth/idp/module/views/login.vm
+idp.authn.Password.2.dest = views/login.vm
+idp.authn.Password.3.src = /net/shibboleth/idp/module/views/login-error.vm
+idp.authn.Password.3.dest = views/login-error.vm
+
 idp.authn.RemoteUser.name = RemoteUser Authentication
 idp.authn.RemoteUser.desc = Login flow for container-based authentication with a dedicated protected path.
 idp.authn.RemoteUser.url = https://wiki.shibboleth.net/confluence/display/IDP4/RemoteUserAuthnConfiguration
@@ -63,6 +74,8 @@ idp.authn.SPNEGO.desc = Login flow for SPNEGO authentication.
 idp.authn.SPNEGO.url = https://wiki.shibboleth.net/confluence/display/IDP4/SPNEGOAuthnConfiguration
 idp.authn.SPNEGO.1.src = /net/shibboleth/idp/module/conf/authn/spnego-authn-config.xml
 idp.authn.SPNEGO.1.dest = conf/authn/spnego-authn-config.xml
+idp.authn.SPNEGO.2.src = /net/shibboleth/idp/module/views/spnego-unavailable.vm
+idp.authn.SPNEGO.2.dest = views/spnego-unavailable.vm
 
 idp.authn.X509.name = X509 Authentication
 idp.authn.X509.desc = Login flow for X.509 authentication with a dedicated protected path.
diff --git a/idp-conf/src/main/resources/conf/authn/password-authn-config.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/password-authn-config.xml
similarity index 73%
copy from idp-conf/src/main/resources/conf/authn/password-authn-config.xml
copy to idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/password-authn-config.xml
index 9892392ca..811b0bf42 100644
--- a/idp-conf/src/main/resources/conf/authn/password-authn-config.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/conf/authn/password-authn-config.xml
@@ -12,37 +12,10 @@
        default-init-method="initialize"
        default-destroy-method="destroy">
     
-    <!--
-    You can optionally comment out anything you don't need, but make sure not to
-    reference the corresponding validator in the list below if you do remove any.
-    -->
-    <import resource="jaas-authn-config.xml" />
-    <import resource="krb5-authn-config.xml" />
-    <import resource="ldap-authn-config.xml" />
-    
     <!-- Ordered list of CredentialValidators to apply to a request. -->
     <util:list id="shibboleth.authn.Password.Validators">
         <ref bean="shibboleth.LDAPValidator" />
     </util:list>
-    
-    <!-- Controls whether all validators in the above bean have to succeed, or just one. -->
-    <util:constant id="shibboleth.authn.Password.RequireAll" static-field="java.lang.Boolean.FALSE"/>
-    
-    <!-- This allows the password to be best-effort cleared after use. -->
-    <util:constant id="shibboleth.authn.Password.RemoveAfterValidation" static-field="java.lang.Boolean.TRUE"/>
-
-    <!-- Set to TRUE if you want the password kept in the resulting Subject as a private credential. -->
-    <util:constant id="shibboleth.authn.Password.RetainAsPrivateCredential" static-field="java.lang.Boolean.FALSE"/>
-    
-    <!-- Names of form fields to pull username and password from. -->
-    <bean id="shibboleth.authn.Password.UsernameFieldName" class="java.lang.String" c:_0="j_username" />
-    <bean id="shibboleth.authn.Password.PasswordFieldName" class="java.lang.String" c:_0="j_password" />
-    <bean id="shibboleth.authn.Password.SSOBypassFieldName" class="java.lang.String" c:_0="donotcache" />
-
-    <!-- Simple transforms to apply to username before validation. -->
-    <util:constant id="shibboleth.authn.Password.Lowercase" static-field="java.lang.Boolean.FALSE"/>
-    <util:constant id="shibboleth.authn.Password.Uppercase" static-field="java.lang.Boolean.FALSE"/>
-    <util:constant id="shibboleth.authn.Password.Trim" static-field="java.lang.Boolean.TRUE"/>
 
     <!-- Apply any regular expression replacement pairs to username before validation. -->
     <util:list id="shibboleth.authn.Password.Transforms">
@@ -109,6 +82,9 @@
     </util:map>
 
     <!--
+    WARNING: This set of features is generally discouraged in favor of the MFA flow,
+    and while not deprecated, is not recommended for new deployments.
+    
     Configuration of "extended" login methods to offer in the password login form.
     
     The String bean is a regular expression identifying the flows to offer. These flows
diff --git a/idp-conf/src/main/resources/views/login-error.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/login-error.vm
similarity index 100%
rename from idp-conf/src/main/resources/views/login-error.vm
rename to idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/login-error.vm
diff --git a/idp-conf/src/main/resources/views/login.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/login.vm
similarity index 100%
rename from idp-conf/src/main/resources/views/login.vm
rename to idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/login.vm
diff --git a/idp-conf/src/main/resources/views/spnego-unavailable.vm b/idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/spnego-unavailable.vm
similarity index 100%
rename from idp-conf/src/main/resources/views/spnego-unavailable.vm
rename to idp-conf-impl/src/main/resources/net/shibboleth/idp/module/views/spnego-unavailable.vm
diff --git a/idp-conf/src/main/resources/conf/authn/authn.properties b/idp-conf/src/main/resources/conf/authn/authn.properties
index ad76f5e19..60475a52c 100644
--- a/idp-conf/src/main/resources/conf/authn/authn.properties
+++ b/idp-conf/src/main/resources/conf/authn/authn.properties
@@ -37,11 +37,41 @@ idp.authn.flows = Password
 #idp.authn.Password.order = 1000
 #idp.authn.Password.passiveAuthenticationSupported = true
 #idp.authn.Password.forcedAuthenticationSupported = true
+# Override this and removeAfterValidation to require all validators to succeed
+#idp.authn.Password.requireAll = false
+# Override to keep the password around
+#idp.authn.Password.removeAfterValidation = true
+# Override to store password in Java Subject
+#idp.authn.Password.retainAsPrivateCredential = false
+# Simple username transforms before validation
+#idp.authn.Password.trim = true
+#idp.authn.Password.lowercase = false
+#idp.authn.Password.uppercase = false
+# Override default form field names
+#idp.authn.Password.usernameFieldName = j_username
+#idp.authn.Password.passwordFieldName = j_password
+#idp.authn.Password.ssoBypassFieldName = donotcache
+# Unset if using customized Principals per validator
+#idp.authn.Password.addDefaultPrincipals = true
 # The Principal collection below is the typical default if not otherwise noted.
 #idp.authn.Password.supportedPrincipals = \
 #    saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport, \
 #    saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Password, \
 #    saml1/urn:oasis:names:tc:SAML:1.0:am:password
+# Validators are controlled in password-authn-config.xml
+
+#### Password Backends ####
+
+# See ldap.properties for LDAP authn properties
+# Kerberos settings
+#idp.authn.Krb5.refreshConfig = false
+#idp.authn.Krb5.preserveTicket = false
+# Set next two for KDC verification
+#idp.authn.Krb5.servicePrincipal = 
+#idp.authn.Krb5.keytab = 
+# JAAS settings
+#idp.authn.JAAS.loginConfigNames = ShibUserPassAuth
+#idp.authn.JAAS.loginConfig = %{idp.home}/conf/authn/jaas.config
 
 #### External ####
 
@@ -72,9 +102,9 @@ idp.authn.External.externalAuthnPath = contextRelative:external.jsp
 #idp.authn.RemoteUserInternal.checkAttributes = 
 #idp.authn.RemoteUserInternal.checkHeaders = 
 # Simple transforms to apply
-#idp.authn.RemoteUserInternal.Trim = true
-#idp.authn.RemoteUserInternal.Lowercase = false
-#idp.authn.RemoteUserInternal.Uppercase = false
+#idp.authn.RemoteUserInternal.trim = true
+#idp.authn.RemoteUserInternal.lowercase = false
+#idp.authn.RemoteUserInternal.uppercase = false
 #idp.authn.RemoteUserInternal.allowedUsernames = 
 #idp.authn.RemoteUserInternal.deniedUsernames = 
 
@@ -173,3 +203,4 @@ idp.authn.MFA.supportedPrincipals = \
     saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport, \
     saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Password, \
     saml1/urn:oasis:names:tc:SAML:1.0:am:password
+# Most actual setup via mfa-authn-config.xml
diff --git a/idp-conf/src/main/resources/conf/authn/jaas-authn-config.xml b/idp-conf/src/main/resources/conf/authn/jaas-authn-config.xml
deleted file mode 100644
index 7edd41c92..000000000
--- a/idp-conf/src/main/resources/conf/authn/jaas-authn-config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:util="http://www.springframework.org/schema/util"
-       xmlns:p="http://www.springframework.org/schema/p"
-       xmlns:c="http://www.springframework.org/schema/c"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
-                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
-                           
-       default-init-method="initialize"
-       default-destroy-method="destroy">
-    
-    <!-- Specify your JAAS config. -->
-    <bean id="JAASConfig" class="org.springframework.core.io.FileSystemResource" c:path="%{idp.home}/conf/authn/jaas.config" />
-    
-    <util:property-path id="shibboleth.authn.JAAS.JAASConfigURI" path="JAASConfig.URI" />
-    
-    <!-- Specify the application name(s) in the JAAS config. -->
-    <util:list id="shibboleth.authn.JAAS.LoginConfigNames">
-        <value>ShibUserPassAuth</value>
-    </util:list>
-
-</beans>
diff --git a/idp-conf/src/main/resources/conf/authn/jaas.config b/idp-conf/src/main/resources/conf/authn/jaas.config
deleted file mode 100644
index 232e93d42..000000000
--- a/idp-conf/src/main/resources/conf/authn/jaas.config
+++ /dev/null
@@ -1,11 +0,0 @@
-ShibUserPassAuth {
-    /*
-	com.sun.security.auth.module.Krb5LoginModule required;
-	*/
-
-    org.ldaptive.jaas.LdapLoginModule required
-      ldapUrl="ldap://localhost:10389"
-      baseDn="ou=people,dc=example,dc=org"
-      userFilter="uid={user}";
-
-};
\ No newline at end of file
diff --git a/idp-conf/src/main/resources/conf/authn/krb5-authn-config.xml b/idp-conf/src/main/resources/conf/authn/krb5-authn-config.xml
deleted file mode 100644
index f826f306e..000000000
--- a/idp-conf/src/main/resources/conf/authn/krb5-authn-config.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:util="http://www.springframework.org/schema/util"
-       xmlns:p="http://www.springframework.org/schema/p"
-       xmlns:c="http://www.springframework.org/schema/c"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
-                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
-                           
-       default-init-method="initialize"
-       default-destroy-method="destroy">
-    
-    <util:constant id="shibboleth.authn.Krb5.RefreshConfig" static-field="java.lang.Boolean.FALSE" />
-
-    <util:constant id="shibboleth.authn.Krb5.PreserveTicket" static-field="java.lang.Boolean.FALSE" />
-
-    <!--
-    Uncomment these beans to perform KDC verification using a service principal and keytab.
-    The keytab bean must be an absolute file pathname and not a reference to a classpath resource,
-    so if idp.home is not a path, don't use it in the value.
-    -->
-    <!--
-    <bean id="shibboleth.authn.Krb5.ServicePrincipal" class="java.lang.String" c:_0="SERVICE/principal" />
-    <bean id="shibboleth.authn.Krb5.Keytab" class="java.lang.String" c:_0="%{idp.home}/credentials/keytab" />
-    -->
-
-</beans>
diff --git a/idp-conf/src/main/resources/conf/authn/ldap-authn-config.xml b/idp-conf/src/main/resources/conf/authn/ldap-authn-config.xml
deleted file mode 100644
index 22a760be9..000000000
--- a/idp-conf/src/main/resources/conf/authn/ldap-authn-config.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
-                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
-       default-init-method="initialize"
-       default-destroy-method="destroy"
-       default-lazy-init="true">
-
-    <!--
-    Default behavior is to rely on properties to populate the various beans.
-    You can override these, particularly shibboleth.authn.LDAP.authenticator,
-    to customize the settings or avoid use of properties.
-    
-    Be cautious of any direct dependency on ldaptive classes to simplify upgrades.
-    -->
-
-    <bean id="shibboleth.authn.LDAP.returnAttributes" parent="shibboleth.CommaDelimStringArray">
-        <constructor-arg type="java.lang.String" value="%{idp.authn.LDAP.returnAttributes:1.1}" />
-    </bean>
-
-    <bean id="shibboleth.authn.LDAP.trustCertificates" parent="shibboleth.X509ResourceCredentialConfig"
-        p:trustCertificates="%{idp.authn.LDAP.trustCertificates:undefined}" />
-        
-    <bean id="shibboleth.authn.LDAP.truststore" parent="shibboleth.KeystoreResourceCredentialConfig"
-        p:truststore="%{idp.authn.LDAP.trustStore:undefined}" />
-        
-    <bean id="shibboleth.authn.LDAP.authenticator" parent="shibboleth.LDAPAuthenticationFactory" lazy-init="true" />
-
-</beans>
diff --git a/idp-conf/src/test/resources/conf/authn/jaas-authn-config.xml b/idp-conf/src/test/resources/conf/authn/jaas-authn-config.xml
deleted file mode 100644
index 7f953a798..000000000
--- a/idp-conf/src/test/resources/conf/authn/jaas-authn-config.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:util="http://www.springframework.org/schema/util"
-       xmlns:p="http://www.springframework.org/schema/p"
-       xmlns:c="http://www.springframework.org/schema/c"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
-                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
-                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
-                           
-       default-init-method="initialize"
-       default-destroy-method="destroy">
-    
-    <!-- Specify your JAAS config. -->
-    <bean id="JAASConfig" class="org.springframework.core.io.ClassPathResource" c:path="%{idp.home}/conf/authn/jaas.config" />
-    
-    <util:property-path id="shibboleth.authn.JAAS.JAASConfigURI" path="JAASConfig.URI" />
-    
-    <!-- Specify the application name(s) in the JAAS config. -->
-    <util:list id="shibboleth.authn.JAAS.LoginConfigNames">
-        <value>ShibUserPassAuth</value>
-    </util:list>
-
-</beans>
diff --git a/idp-conf/src/main/resources/conf/authn/password-authn-config.xml b/idp-conf/src/test/resources/conf/authn/password-authn-config.xml
similarity index 73%
rename from idp-conf/src/main/resources/conf/authn/password-authn-config.xml
rename to idp-conf/src/test/resources/conf/authn/password-authn-config.xml
index 9892392ca..811b0bf42 100644
--- a/idp-conf/src/main/resources/conf/authn/password-authn-config.xml
+++ b/idp-conf/src/test/resources/conf/authn/password-authn-config.xml
@@ -12,37 +12,10 @@
        default-init-method="initialize"
        default-destroy-method="destroy">
     
-    <!--
-    You can optionally comment out anything you don't need, but make sure not to
-    reference the corresponding validator in the list below if you do remove any.
-    -->
-    <import resource="jaas-authn-config.xml" />
-    <import resource="krb5-authn-config.xml" />
-    <import resource="ldap-authn-config.xml" />
-    
     <!-- Ordered list of CredentialValidators to apply to a request. -->
     <util:list id="shibboleth.authn.Password.Validators">
         <ref bean="shibboleth.LDAPValidator" />
     </util:list>
-    
-    <!-- Controls whether all validators in the above bean have to succeed, or just one. -->
-    <util:constant id="shibboleth.authn.Password.RequireAll" static-field="java.lang.Boolean.FALSE"/>
-    
-    <!-- This allows the password to be best-effort cleared after use. -->
-    <util:constant id="shibboleth.authn.Password.RemoveAfterValidation" static-field="java.lang.Boolean.TRUE"/>
-
-    <!-- Set to TRUE if you want the password kept in the resulting Subject as a private credential. -->
-    <util:constant id="shibboleth.authn.Password.RetainAsPrivateCredential" static-field="java.lang.Boolean.FALSE"/>
-    
-    <!-- Names of form fields to pull username and password from. -->
-    <bean id="shibboleth.authn.Password.UsernameFieldName" class="java.lang.String" c:_0="j_username" />
-    <bean id="shibboleth.authn.Password.PasswordFieldName" class="java.lang.String" c:_0="j_password" />
-    <bean id="shibboleth.authn.Password.SSOBypassFieldName" class="java.lang.String" c:_0="donotcache" />
-
-    <!-- Simple transforms to apply to username before validation. -->
-    <util:constant id="shibboleth.authn.Password.Lowercase" static-field="java.lang.Boolean.FALSE"/>
-    <util:constant id="shibboleth.authn.Password.Uppercase" static-field="java.lang.Boolean.FALSE"/>
-    <util:constant id="shibboleth.authn.Password.Trim" static-field="java.lang.Boolean.TRUE"/>
 
     <!-- Apply any regular expression replacement pairs to username before validation. -->
     <util:list id="shibboleth.authn.Password.Transforms">
@@ -109,6 +82,9 @@
     </util:map>
 
     <!--
+    WARNING: This set of features is generally discouraged in favor of the MFA flow,
+    and while not deprecated, is not recommended for new deployments.
+    
     Configuration of "extended" login methods to offer in the password login form.
     
     The String bean is a regular expression identifying the flows to offer. These flows

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


More information about the commits mailing list