[java-identity-provider] branch master updated: IDP-1635 - "No lockout key returned for request" after authentication

Scott Cantor cantor.2 at osu.edu
Tue Jul 7 17:00:45 UTC 2020


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

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

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

The following commit(s) were added to refs/heads/master by this push:
       new  db431514d IDP-1635 - "No lockout key returned for request" after authentication
db431514d is described below

commit db431514d4f778dcba652bb81105b45d4a82910f
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jul 7 13:00:50 2020 -0400

    IDP-1635 - "No lockout key returned for request" after authentication
    
    https://issues.shibboleth.net/jira/browse/IDP-1635
    
    Also revamped context cleanup option handling.
---
 .../idp/authn/AbstractCredentialValidator.java     |  2 +-
 ...bstractUsernamePasswordCredentialValidator.java | 10 +++-
 .../idp/authn/AbstractValidationAction.java        | 61 ++++++++++++++++++++++
 .../impl/StorageBackedAccountLockoutManager.java   |  2 +-
 .../idp/authn/impl/ValidateCredentials.java        | 37 +++++++++++--
 .../authn/impl/ValidateExternalAuthentication.java | 10 ++--
 .../idp/authn/impl/ValidateFunctionResult.java     | 10 ++--
 .../idp/authn/impl/ValidateRemoteUser.java         |  4 +-
 .../idp/authn/impl/ValidateUserAgentAddress.java   |  4 +-
 .../idp/authn/impl/ValidateX509Certificate.java    |  6 +--
 .../resources/conf/authn/password-authn-config.xml | 10 ++--
 .../system/flows/authn/password-authn-beans.xml    |  6 ++-
 12 files changed, 132 insertions(+), 30 deletions(-)

diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractCredentialValidator.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractCredentialValidator.java
index df873bf3e..9ac11ec8c 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractCredentialValidator.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AbstractCredentialValidator.java
@@ -73,7 +73,7 @@ public abstract class AbstractCredentialValidator extends AbstractIdentifiedInit
     
     /** {@inheritDoc} */
     @Override
-    public void setId(final String id) {
+    public synchronized void setId(final String id) {
         super.setId(id);
     }
     
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 4e2674fca..953f7736f 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
@@ -89,7 +89,6 @@ public abstract class AbstractUsernamePasswordCredentialValidator extends Abstra
     /** Constructor. */
     public AbstractUsernamePasswordCredentialValidator() {
         usernamePasswordContextLookupStrategy = new ChildContextLookup<>(UsernamePasswordContext.class);
-        removeContextAfterValidation = true;
 
         transforms = Collections.emptyList();
         
@@ -138,7 +137,10 @@ public abstract class AbstractUsernamePasswordCredentialValidator extends Abstra
      * <p>Defaults to true</p>
      * 
      * @return whether to remove the context after successful validation
+     * 
+     * @deprecated
      */
+    @Deprecated(since="4.1.0", forRemoval=true)
     public boolean removeContextAfterValidation() {
         return removeContextAfterValidation;
     }
@@ -148,7 +150,10 @@ public abstract class AbstractUsernamePasswordCredentialValidator extends Abstra
      * successfully validated.
      * 
      * @param flag  flag to set
+     * 
+     * @deprecated
      */
+    @Deprecated(since="4.1.0", forRemoval=true)
     public void setRemoveContextAfterValidation(final boolean flag) {
         ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
         
@@ -295,7 +300,8 @@ public abstract class AbstractUsernamePasswordCredentialValidator extends Abstra
         if (savePasswordToCredentialSet) {
             subject.getPrivateCredentials().add(new PasswordPrincipal(usernamePasswordContext.getPassword()));
         }
-        
+
+        // This is migrating out to the validation action, leaving code here for now but we won't use it.
         if (removeContextAfterValidation) {
             usernamePasswordContext.getParent().removeSubcontext(usernamePasswordContext);
             usernamePasswordContext.setPassword(null);
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 f5f208fa7..ba7386439 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.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 
@@ -87,6 +88,9 @@ public abstract class AbstractValidationAction extends AbstractAuthenticationAct
     /** Indicates whether to clear any existing {@link AuthenticationErrorContext} before execution. */
     private boolean clearErrorContext;
     
+    /** A cleanup hook to execute after successful validation. */
+    @Nullable private Consumer<ProfileRequestContext> cleanupHook;
+    
     /** Error messages associated with a specific error condition token. */
     @Nonnull @NonnullElements private Map<String,Collection<String>> classifiedMessages;
     
@@ -206,6 +210,30 @@ public abstract class AbstractValidationAction extends AbstractAuthenticationAct
         resultCachingPredicate = predicate;
     }
     
+    /**
+     * Get the cleanup hook to execute after successful validation.
+     * 
+     * @return cleanup hook
+     * 
+     * @since 4.1.0
+     */
+    @Nullable public Consumer<ProfileRequestContext> getCleanupHook() {
+        return cleanupHook;
+    }
+    
+    /**
+     * Set the cleanup hook to execute after successful validation.
+     * 
+     * @param hook cleanup hook
+     * 
+     * @since 4.1.0
+     */
+    public void setCleanupHook(@Nullable final Consumer<ProfileRequestContext> hook) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        
+        cleanupHook = hook;
+    }
+    
     /**
      * Get the strategy used to locate the requester ID for canonicalization.
      * 
@@ -403,7 +431,10 @@ public abstract class AbstractValidationAction extends AbstractAuthenticationAct
      * nothing if the metrics registry is not installed into the runtime.
      * 
      * @since 3.3.0
+     * 
+     * @deprecated
      */
+    @Deprecated(since="4.1.0", forRemoval=true)
     protected void recordSuccess() {
         if (MetricsSupport.getMetricRegistry() != null) {
             MetricsSupport.getMetricRegistry().counter(getMetricName() + ".successes").inc();
@@ -415,13 +446,43 @@ public abstract class AbstractValidationAction extends AbstractAuthenticationAct
      * nothing if the metrics registry is not installed into the runtime.
      * 
      * @since 3.3.0
+     * 
+     * @deprecated
      */
+    @Deprecated(since="4.1.0", forRemoval=true)
     protected void recordFailure() {
         if (MetricsSupport.getMetricRegistry() != null) {
             MetricsSupport.getMetricRegistry().counter(getMetricName() + ".failures").inc();
         }
     }
     
+    /**
+     * Record a successful authentication attempt against the configured counter. Records
+     * nothing if the metrics registry is not installed into the runtime.
+     * 
+     * @param profileRequestContext profile request context
+     * 
+     * @since 4.1.0
+     */
+    protected void recordSuccess(@Nonnull final ProfileRequestContext profileRequestContext) {
+        recordSuccess();
+        if (cleanupHook != null) {
+            cleanupHook.accept(profileRequestContext);
+        }
+    }
+    
+    /**
+     * Record a failed authentication attempt against the configured counter. Records
+     * nothing if the metrics registry is not installed into the runtime.
+     * 
+     * @param profileRequestContext profile request context
+     * 
+     * @since 4.1.0
+     */
+    protected void recordFailure(@Nonnull final ProfileRequestContext profileRequestContext) {
+        recordFailure();
+    }
+    
     /**
      * Adds an exception encountered during the action to an {@link AuthenticationErrorContext}, creating one if
      * necessary, beneath the {@link AuthenticationContext}.
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/StorageBackedAccountLockoutManager.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/StorageBackedAccountLockoutManager.java
index cfb9b3db9..3b7fd79e8 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/StorageBackedAccountLockoutManager.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/StorageBackedAccountLockoutManager.java
@@ -124,7 +124,7 @@ public class StorageBackedAccountLockoutManager extends AbstractIdentifiableInit
         ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
         
         maxAttemptsLookupStrategy = FunctionSupport.constant(
-                (int) Constraint.isGreaterThan(0, attempts, "Attempts must be greater than zero"));
+                Constraint.isGreaterThan(0, attempts, "Attempts must be greater than zero"));
     }
     
     /**
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 33c5fea8f..f0fce76c9 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
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.function.Consumer;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -34,6 +35,7 @@ import net.shibboleth.idp.authn.CredentialValidator;
 import net.shibboleth.idp.authn.CredentialValidator.ErrorHandler;
 import net.shibboleth.idp.authn.CredentialValidator.WarningHandler;
 import net.shibboleth.idp.authn.context.AuthenticationContext;
+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;
@@ -64,7 +66,7 @@ public class ValidateCredentials extends AbstractValidationAction implements War
     
     /** Ordered list of validators. */
     @Nonnull @NonnullElements private List<CredentialValidator> credentialValidators;
-    
+        
     /** Whether all validators must succeed. */
     private boolean requireAll;
 
@@ -195,7 +197,7 @@ public class ValidateCredentials extends AbstractValidationAction implements War
                     return;
                 }
             } catch (final Exception e) {
-                recordFailure();
+                recordFailure(profileRequestContext);
                 if (requireAll) {
                     super.handleError(profileRequestContext, authenticationContext, e, AuthnEventIds.AUTHN_EXCEPTION);
                     errorSignaled = true;
@@ -252,9 +254,36 @@ public class ValidateCredentials extends AbstractValidationAction implements War
      * @param profileRequestContext current profile request context
      */
     protected void recordSuccess(@Nonnull final ProfileRequestContext profileRequestContext) {
-        recordSuccess();
+        // Need to do this first because the superclass's method will call the cleanup hook.
         if (lockoutManager != null) {
-            lockoutManager.clear(profileRequestContext);
+            if (!lockoutManager.clear(profileRequestContext)) {
+                log.warn("{} Failed to clear lockout state", getLogPrefix());
+            }
+        }
+        super.recordSuccess(profileRequestContext);
+    }
+
+    /**
+     * A default cleanup hook that removes the {@link UsernamePasswordContext} from the tree.
+     * 
+     * It also "clears" the password field, but this won't be useful until we get off the String type.
+     * 
+     * @since 4.1.0
+     */
+    public static class UsernamePasswordCleanupHook implements Consumer<ProfileRequestContext> {
+
+        /** {@inheritDoc} */
+        public void accept(@Nullable final ProfileRequestContext input) {
+            if (input != null) {
+                final AuthenticationContext authnCtx = input.getSubcontext(AuthenticationContext.class);
+                if (authnCtx != null) {
+                    final UsernamePasswordContext upCtx = authnCtx.getSubcontext(UsernamePasswordContext.class);
+                    if (upCtx != null) {
+                        upCtx.setPassword(null);
+                        authnCtx.removeSubcontext(upCtx);
+                    }
+                }
+            }
         }
     }
 
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
index 70be416fb..dfbe3ca56 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateExternalAuthentication.java
@@ -144,7 +144,7 @@ public class ValidateExternalAuthentication extends AbstractValidationAction {
         if (extContext == null) {
             log.debug("{} No ExternalAuthenticationContext available within authentication context", getLogPrefix());
             ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_AUTHN_CTX);
-            recordFailure();
+            recordFailure(profileRequestContext);
             return false;
         }
         
@@ -161,14 +161,14 @@ public class ValidateExternalAuthentication extends AbstractValidationAction {
             log.info("{} External authentication produced exception", getLogPrefix(), extContext.getAuthnException());
             handleError(profileRequestContext, authenticationContext, extContext.getAuthnException(),
                     AuthnEventIds.AUTHN_EXCEPTION);
-            recordFailure();
+            recordFailure(profileRequestContext);
             return;
         } else if (extContext.getAuthnError() != null) {
             log.info("{} External authentication produced error message: {}", getLogPrefix(),
                     extContext.getAuthnError());
             handleError(profileRequestContext, authenticationContext, extContext.getAuthnError(),
                     AuthnEventIds.AUTHN_EXCEPTION);
-            recordFailure();
+            recordFailure(profileRequestContext);
             return;
         }
         
@@ -196,11 +196,11 @@ public class ValidateExternalAuthentication extends AbstractValidationAction {
         if (!checkUsername(extContext.getSubject())) {
             handleError(profileRequestContext, authenticationContext, AuthnEventIds.INVALID_CREDENTIALS,
                     AuthnEventIds.INVALID_CREDENTIALS);
-            recordFailure();
+            recordFailure(profileRequestContext);
             return;
         }
         
-        recordSuccess();
+        recordSuccess(profileRequestContext);
         
         if (!extContext.getAuthenticatingAuthorities().isEmpty()) {
             final ProxyAuthenticationPrincipal proxied =
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateFunctionResult.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateFunctionResult.java
index 144068db5..3af9d2d18 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateFunctionResult.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateFunctionResult.java
@@ -106,23 +106,23 @@ public class ValidateFunctionResult extends AbstractValidationAction {
         if (result == null) {
             log.info("{} Authentication by function failed", getLogPrefix());
             ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_CREDENTIALS);
-            recordFailure();
+            recordFailure(profileRequestContext);
         } else if (result instanceof String) {
             log.info("{} Validated user via name '{}'", getLogPrefix(), result);
-            recordSuccess();
+            recordSuccess(profileRequestContext);
             buildAuthenticationResult(profileRequestContext, authenticationContext);
         } else if (result instanceof Principal) {
             log.info("{} Validated user via Principal '{}'", getLogPrefix(), result);
-            recordSuccess();
+            recordSuccess(profileRequestContext);
             buildAuthenticationResult(profileRequestContext, authenticationContext);
         } else if (result instanceof Subject) {
             log.info("{} Validated user via Subject", getLogPrefix());
-            recordSuccess();
+            recordSuccess(profileRequestContext);
             buildAuthenticationResult(profileRequestContext, authenticationContext);
         } else {
             log.info("{} Authentication by function failed, result type was invalid", getLogPrefix());
             ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_CREDENTIALS);
-            recordFailure();
+            recordFailure(profileRequestContext);
         }
     }
     
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateRemoteUser.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateRemoteUser.java
index 843e912c3..2aa7fc77a 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateRemoteUser.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateRemoteUser.java
@@ -148,12 +148,12 @@ public class ValidateRemoteUser extends AbstractValidationAction {
         if (!isAuthenticated(usernameContext.getUsername())) {
             log.info("{} User '{}' was not valid", getLogPrefix(), usernameContext.getUsername());
             ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_CREDENTIALS);
-            recordFailure();
+            recordFailure(profileRequestContext);
             return;
         }
 
         log.info("{} Validated user '{}'", getLogPrefix(), usernameContext.getUsername());
-        recordSuccess();
+        recordSuccess(profileRequestContext);
         buildAuthenticationResult(profileRequestContext, authenticationContext);
     }
     
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateUserAgentAddress.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateUserAgentAddress.java
index 259139565..fe012c123 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateUserAgentAddress.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateUserAgentAddress.java
@@ -134,7 +134,7 @@ public class ValidateUserAgentAddress extends AbstractValidationAction {
                 principalName = e.getKey();
                 log.info("{} Authenticated user agent with address {} as {}",
                         getLogPrefix(), uaContext.getAddress().getHostAddress(), principalName);
-                recordSuccess();
+                recordSuccess(profileRequestContext);
                 buildAuthenticationResult(profileRequestContext, authenticationContext);
                 return;
             }
@@ -143,7 +143,7 @@ public class ValidateUserAgentAddress extends AbstractValidationAction {
         log.debug("{} User agent with address {} was not authenticated", getLogPrefix(),
                 uaContext.getAddress().getHostAddress());
         ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.INVALID_CREDENTIALS);
-        recordFailure();
+        recordFailure(profileRequestContext);
     }
 
     /**
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateX509Certificate.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateX509Certificate.java
index ce173a226..44c8efd81 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateX509Certificate.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/ValidateX509Certificate.java
@@ -137,13 +137,13 @@ public class ValidateX509Certificate extends AbstractValidationAction {
                     log.warn("{} Trust engine failed to validate X.509 certificate", getLogPrefix());
                     handleError(profileRequestContext, authenticationContext, AuthnEventIds.INVALID_CREDENTIALS,
                             AuthnEventIds.INVALID_CREDENTIALS);
-                    recordFailure();
+                    recordFailure(profileRequestContext);
                     return;
                 }
             } catch (final SecurityException e) {
                 log.error("{} Exception raised by trust engine", getLogPrefix(), e);
                 handleError(profileRequestContext, authenticationContext, e, AuthnEventIds.INVALID_CREDENTIALS);
-                recordFailure();
+                recordFailure(profileRequestContext);
                 return;
             }
         } else {
@@ -152,7 +152,7 @@ public class ValidateX509Certificate extends AbstractValidationAction {
 
         log.info("{} Login by '{}' succeeded", getLogPrefix(),
                 ((X509Certificate) certContext.getCertificate()).getSubjectX500Principal().getName());
-        recordSuccess();
+        recordSuccess(profileRequestContext);
         buildAuthenticationResult(profileRequestContext, authenticationContext);
         ActionSupport.buildProceedEvent(profileRequestContext);
     }
diff --git a/idp-conf/src/main/resources/conf/authn/password-authn-config.xml b/idp-conf/src/main/resources/conf/authn/password-authn-config.xml
index 73ac7f8a3..9892392ca 100644
--- a/idp-conf/src/main/resources/conf/authn/password-authn-config.xml
+++ b/idp-conf/src/main/resources/conf/authn/password-authn-config.xml
@@ -28,6 +28,11 @@
     <!-- 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" />
@@ -39,9 +44,6 @@
     <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"/>
 
-    <!-- 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"/>
-
     <!-- Apply any regular expression replacement pairs to username before validation. -->
     <util:list id="shibboleth.authn.Password.Transforms">
         <!--
@@ -58,7 +60,7 @@
         p:lockoutDuration="PT5M"
         p:extendLockoutDuration="false" />
     -->
-
+      
     <!--
     Define entries here to map error messages detected by validation actions and classify them as particular
     kinds of errors for use in your templates and as events in flows.
diff --git a/idp-conf/src/main/resources/system/flows/authn/password-authn-beans.xml b/idp-conf/src/main/resources/system/flows/authn/password-authn-beans.xml
index 4a8b1786c..a6a3cc5dc 100644
--- a/idp-conf/src/main/resources/system/flows/authn/password-authn-beans.xml
+++ b/idp-conf/src/main/resources/system/flows/authn/password-authn-beans.xml
@@ -42,6 +42,8 @@
         class="net.shibboleth.idp.authn.impl.PopulateSubjectCanonicalizationContext" scope="prototype"
         p:availableFlows-ref="shibboleth.PostLoginSubjectCanonicalizationFlows" />
     
+    <bean id="DefaultCleanupHook" class="net.shibboleth.idp.authn.impl.ValidateCredentials.UsernamePasswordCleanupHook" />
+    
     <!-- New action bean that uses CredentialValidator chains. -->    
     <bean id="ValidateCredentials"
         class="net.shibboleth.idp.authn.impl.ValidateCredentials" scope="prototype"
@@ -53,13 +55,15 @@
         p:supportedPrincipals="#{getObject('shibboleth.authn.Password.PrincipalOverride')}"
         p:classifiedMessages-ref="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: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:removeContextAfterValidation="#{getObject('shibboleth.authn.Password.RemoveAfterValidation') ?: true}"
         p:lowercase-ref="shibboleth.authn.Password.Lowercase"
         p:uppercase-ref="shibboleth.authn.Password.Uppercase"
         p:trim-ref="shibboleth.authn.Password.Trim"

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


More information about the commits mailing list