[java-identity-provider] branch main updated: IDP-2406 - Support max-age generically in IdP profile config

Codeberg noreply at shibboleth.net
Wed Jan 7 00:10:58 UTC 2026


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

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

View the commit online:
https://codeberg.org/Shibboleth/java-identity-provider/commit/a0d6e23c8ffef6b94e74b272248c6a444e7f8714

The following commit(s) were added to refs/heads/main by this push:
     new a0d6e23c8 IDP-2406 - Support max-age generically in IdP profile config
a0d6e23c8 is described below

commit a0d6e23c8ffef6b94e74b272248c6a444e7f8714
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Tue Jan 6 19:10:42 2026 -0500

    IDP-2406 - Support max-age generically in IdP profile config
    
    https://shibboleth.atlassian.net/browse/IDP-2406
    
    Added to AuthenticationProfileConfiguration.
    Extracted setting in SAML, CAS, and Admin flows.
---
 .../config/AuthenticationProfileConfiguration.java | 18 +++++++++++
 .../AuthenticationFlowsLookupFunction.java         |  2 +-
 ...okupFunction.java => MaxAgeLookupFunction.java} | 18 +++++------
 .../idp/cas/config/LoginConfiguration.java         | 35 +++++++++++++++++++++
 .../impl/BuildAuthenticationContextAction.java     |  4 +++
 .../shibboleth/idp/conf/relying-party-mddriven.xml |  9 ++++++
 .../impl/InitializeAuthenticationContext.java      | 21 +++++++++++++
 .../impl/BrowserSSOProfileConfiguration.java       | 36 ++++++++++++++++++++++
 .../impl/BrowserSSOProfileConfiguration.java       | 35 +++++++++++++++++++++
 9 files changed, 167 insertions(+), 11 deletions(-)

diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/AuthenticationProfileConfiguration.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/AuthenticationProfileConfiguration.java
index acfc9aa97..f498d8d8f 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/AuthenticationProfileConfiguration.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/AuthenticationProfileConfiguration.java
@@ -15,6 +15,7 @@
 package net.shibboleth.idp.authn.config;
 
 import java.security.Principal;
+import java.time.Duration;
 import java.util.List;
 import java.util.Set;
 
@@ -23,6 +24,7 @@ import javax.annotation.Nullable;
 
 import org.opensaml.profile.context.ProfileRequestContext;
 
+import net.shibboleth.idp.authn.AuthenticationResult;
 import net.shibboleth.profile.config.ProfileConfiguration;
 import net.shibboleth.shared.annotation.ConfigurationSetting;
 import net.shibboleth.shared.annotation.constraint.NonNegative;
@@ -88,6 +90,22 @@ public interface AuthenticationProfileConfiguration extends ProfileConfiguration
     @ConfigurationSetting(name="forceAuthn")
     boolean isForceAuthn(@Nullable final ProfileRequestContext profileRequestContext);
     
+    /**
+     * Get duration since an {@link AuthenticationResult} was created that allows it to be
+     * reused for this request.
+     * 
+     * <p>If null, no constraint is applied.</p>
+     * 
+     * @param profileRequestContext profile request context
+     * 
+     * @return allowable duration
+     * 
+     * @since 5.2.0
+     */
+    @Nullable default Duration getMaxAge(@Nullable final ProfileRequestContext profileRequestContext) {
+        return null;
+    }
+    
     /**
      * Gets the maximum number of times an assertion may be proxied outbound and/or
      * the maximum number of hops between the relying party and a proxied authentication
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/navigate/AuthenticationFlowsLookupFunction.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/navigate/AuthenticationFlowsLookupFunction.java
index a3fd3f8c7..c5e06af88 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/navigate/AuthenticationFlowsLookupFunction.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/navigate/AuthenticationFlowsLookupFunction.java
@@ -29,7 +29,7 @@ import net.shibboleth.shared.collection.CollectionSupport;
 import org.opensaml.profile.context.ProfileRequestContext;
 
 /**
- * A function that returns {@link AuthenticationProfileConfiguration#getAuthenticationFlows}()
+ * A function that returns {@link AuthenticationProfileConfiguration#getAuthenticationFlows(ProfileRequestContext)}
  * if such a profile is available from a {@link RelyingPartyContext} obtained via a lookup function,
  * by default a child of the {@link ProfileRequestContext}.
  * 
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/navigate/AuthenticationFlowsLookupFunction.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/navigate/MaxAgeLookupFunction.java
similarity index 73%
copy from idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/navigate/AuthenticationFlowsLookupFunction.java
copy to idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/navigate/MaxAgeLookupFunction.java
index a3fd3f8c7..5edff9e33 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/navigate/AuthenticationFlowsLookupFunction.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/config/navigate/MaxAgeLookupFunction.java
@@ -14,7 +14,7 @@
 
 package net.shibboleth.idp.authn.config.navigate;
 
-import java.util.Collection;
+import java.time.Duration;
 
 import javax.annotation.Nullable;
 
@@ -22,33 +22,31 @@ import net.shibboleth.idp.authn.config.AuthenticationProfileConfiguration;
 import net.shibboleth.profile.config.ProfileConfiguration;
 import net.shibboleth.profile.context.RelyingPartyContext;
 import net.shibboleth.profile.context.navigate.AbstractRelyingPartyLookupFunction;
-import net.shibboleth.shared.annotation.constraint.NotLive;
-import net.shibboleth.shared.annotation.constraint.Unmodifiable;
-import net.shibboleth.shared.collection.CollectionSupport;
 
 import org.opensaml.profile.context.ProfileRequestContext;
 
 /**
- * A function that returns {@link AuthenticationProfileConfiguration#getAuthenticationFlows}()
+ * A function that returns {@link AuthenticationProfileConfiguration#getMaxAge(ProfileRequestContext)}
  * if such a profile is available from a {@link RelyingPartyContext} obtained via a lookup function,
  * by default a child of the {@link ProfileRequestContext}.
  * 
  * <p>If a specific setting is unavailable, no values are returned.</p>
+ * 
+ * @since 5.2.0
  */
-public class AuthenticationFlowsLookupFunction extends AbstractRelyingPartyLookupFunction<Collection<String>> {
+public class MaxAgeLookupFunction extends AbstractRelyingPartyLookupFunction<Duration> {
 
     /** {@inheritDoc} */
-    @Nullable @NotLive @Unmodifiable public Collection<String> apply(
-            @Nullable final ProfileRequestContext input) {
+    @Nullable public Duration apply(@Nullable final ProfileRequestContext input) {
         final RelyingPartyContext rpc = getRelyingPartyContextLookupStrategy().apply(input);
         if (rpc != null) {
             final ProfileConfiguration pc = rpc.getProfileConfig();
             if (pc instanceof AuthenticationProfileConfiguration apc) {
-                return apc.getAuthenticationFlows(input);
+                return apc.getMaxAge(input);
             }
         }
         
-        return CollectionSupport.emptyList();
+        return null;
     }
 
 }
\ No newline at end of file
diff --git a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java
index 5e6592388..7438f4782 100644
--- a/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java
+++ b/idp-cas-api/src/main/java/net/shibboleth/idp/cas/config/LoginConfiguration.java
@@ -15,6 +15,7 @@
 package net.shibboleth.idp.cas.config;
 
 import java.security.Principal;
+import java.time.Duration;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
@@ -26,6 +27,7 @@ import javax.annotation.Nullable;
 
 import org.opensaml.profile.context.ProfileRequestContext;
 
+import net.shibboleth.idp.authn.AuthenticationResult;
 import net.shibboleth.idp.authn.config.AuthenticationProfileConfiguration;
 import net.shibboleth.shared.annotation.ConfigurationSetting;
 import net.shibboleth.shared.annotation.constraint.NonNegative;
@@ -72,6 +74,9 @@ public class LoginConfiguration extends AbstractProtocolConfiguration
     
     /** Whether to mandate forced authentication for the request. */
     @Nonnull private Predicate<ProfileRequestContext> forceAuthnPredicate;
+    
+    /** Lookup function for max-age setting. */
+    @Nonnull private Function<ProfileRequestContext,Duration> maxAgeLookupStrategy;
 
     /** Whether to store consent in service tickets. */
     @Nonnull private Predicate<ProfileRequestContext> storeConsentInTicketsPredicate;
@@ -87,6 +92,7 @@ public class LoginConfiguration extends AbstractProtocolConfiguration
         postAuthenticationFlowsLookupStrategy = FunctionSupport.constant(null);
         defaultAuthenticationContextsLookupStrategy = FunctionSupport.constant(null);
         forceAuthnPredicate = PredicateSupport.alwaysFalse();
+        maxAgeLookupStrategy = FunctionSupport.constant(null);
         storeConsentInTicketsPredicate = PredicateSupport.alwaysFalse();
         proxyCountLookupStrategy = FunctionSupport.constant(null);
     }
@@ -230,6 +236,35 @@ public class LoginConfiguration extends AbstractProtocolConfiguration
     public void setForceAuthnPredicate(@Nonnull final Predicate<ProfileRequestContext> condition) {
         forceAuthnPredicate = Constraint.isNotNull(condition, "Forced authentication predicate cannot be null");
     }
+    
+    /** {@inheritDoc} */
+    @ConfigurationSetting(name="maxAge")
+    @Nullable public Duration getMaxAge(@Nullable final ProfileRequestContext profileRequestContext) {
+        return maxAgeLookupStrategy.apply(profileRequestContext);
+    }
+    
+    /**
+     * Sets allowed duration between an {@link AuthenticationResult} creation and its reuse for this request.
+     * 
+     * @param maxAge allowed duration
+     * 
+     * @since 5.2.0
+     */
+    public void setMaxAge(@Nullable final Duration maxAge) {
+        maxAgeLookupStrategy = FunctionSupport.constant(maxAge);
+    }
+
+    /**
+     * Sets lookup strategy for the allowed duration between an {@link AuthenticationResult} creation
+     * and its reuse for this request.
+     * 
+     * @param strategy lookup strategy
+     * 
+     * @since 5.2.0
+     */
+    public void setMaxAgeLookupStrategy(@Nonnull final Function<ProfileRequestContext,Duration> strategy) {
+        maxAgeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+    }
 
     /**
      * Get whether to store consent in service tickets.
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildAuthenticationContextAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildAuthenticationContextAction.java
index 534009062..9b4631b30 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildAuthenticationContextAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/BuildAuthenticationContextAction.java
@@ -78,6 +78,10 @@ public class BuildAuthenticationContextAction
                 ac.setForceAuthn(config.isForceAuthn(profileRequestContext));
             }
         }
+
+        if (config != null) {
+            ac.setMaxAge(config.getMaxAge(profileRequestContext));
+        }
         
         if (!ac.isForceAuthn()) {
             ac.setIsPassive(request.isGateway());
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/relying-party-mddriven.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/relying-party-mddriven.xml
index fb4fcfb5f..2f3772b01 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/relying-party-mddriven.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/relying-party-mddriven.xml
@@ -323,6 +323,9 @@
                 <constructor-arg value="false" />
             </bean>
         </property>
+        <property name="maxAgeLookupStrategy">
+            <bean parent="shibboleth.MDDrivenDurationProperty" p:propertyName="maxAge" />
+        </property>
         <property name="defaultAuthenticationMethodsLookupStrategy">
             <bean parent="shibboleth.MDDrivenListProperty" p:propertyName="defaultAuthenticationMethods"
                 p:propertyType="#{T(net.shibboleth.idp.saml.authn.principal.AuthenticationMethodPrincipal)}" />
@@ -467,6 +470,9 @@
                 </constructor-arg>
             </bean>
         </property>
+        <property name="maxAgeLookupStrategy">
+            <bean parent="shibboleth.MDDrivenDurationProperty" p:propertyName="maxAge" />
+        </property>
         <property name="checkAddressPredicate">
             <bean class="net.shibboleth.shared.logic.PredicateSupport" factory-method="fromFunction">
                 <constructor-arg>
@@ -787,6 +793,9 @@
                 <constructor-arg value="false" />
             </bean>
         </property>
+        <property name="maxAgeLookupStrategy">
+            <bean parent="shibboleth.MDDrivenDurationProperty" p:propertyName="maxAge" />
+        </property>
         <property name="storeConsentInTicketsPredicate">
             <bean class="net.shibboleth.shared.logic.PredicateSupport" factory-method="fromFunction">
                 <constructor-arg>
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/profile/impl/InitializeAuthenticationContext.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/profile/impl/InitializeAuthenticationContext.java
index 6dcad0b47..2daf757a2 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/profile/impl/InitializeAuthenticationContext.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/profile/impl/InitializeAuthenticationContext.java
@@ -14,6 +14,7 @@
 
 package net.shibboleth.idp.saml.profile.impl;
 
+import java.time.Duration;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -36,6 +37,7 @@ import org.opensaml.saml.saml2.core.Subject;
 import org.slf4j.Logger;
 import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.idp.authn.config.navigate.ForceAuthnProfileConfigPredicate;
+import net.shibboleth.idp.authn.config.navigate.MaxAgeLookupFunction;
 import net.shibboleth.idp.authn.context.AuthenticationContext;
 import net.shibboleth.idp.authn.context.SubjectContext;
 import net.shibboleth.idp.profile.AbstractProfileAction;
@@ -75,6 +77,9 @@ public class InitializeAuthenticationContext extends AbstractProfileAction {
     /** Strategy used to determine proxy count from configuration. */
     @Nonnull private Function<ProfileRequestContext,Integer> proxyCountLookupStrategy;
     
+    /** Strategy used to determine max-age from configuration. */
+    @Nonnull private Function<ProfileRequestContext,Duration> maxAgeLookupStrategy;
+    
     /** Strategy used to locate the {@link AuthnRequest} to operate on, if any. */
     @Nonnull private Function<ProfileRequestContext,AuthnRequest> requestLookupStrategy;
     
@@ -87,6 +92,7 @@ public class InitializeAuthenticationContext extends AbstractProfileAction {
         forceAuthnPredicate = new ForceAuthnProfileConfigPredicate();
         ignoreScopingPredicate = new IgnoreScopingProfileConfigPredicate();
         proxyCountLookupStrategy = new ProxyCountLookupFunction();
+        maxAgeLookupStrategy = new MaxAgeLookupFunction();
         final Function<ProfileRequestContext,AuthnRequest> rls =
                 new MessageLookup<>(AuthnRequest.class).compose(new InboundMessageContextLookup());
         assert rls != null;
@@ -142,6 +148,18 @@ public class InitializeAuthenticationContext extends AbstractProfileAction {
         checkSetterPreconditions();
         proxyCountLookupStrategy = Constraint.isNotNull(strategy, "Proxy count lookup strategy cannot be null");
     }
+
+    /**
+     * Set the lookup function to apply to derive max-age from the configuration.
+     * 
+     * @param strategy lookup strategy
+     * 
+     * @since 5.2.0
+     */
+    public void setMaxAgeLookupStrategy(@Nonnull final Function<ProfileRequestContext,Duration> strategy) {
+        checkSetterPreconditions();
+        maxAgeLookupStrategy = Constraint.isNotNull(strategy, "Max-Age lookup strategy cannot be null");
+    }
     
     /**
      * Set the strategy used to locate the {@link AuthnRequest} to examine, if any.
@@ -203,6 +221,9 @@ public class InitializeAuthenticationContext extends AbstractProfileAction {
             authnCtx.setForceAuthn(forceAuthnPredicate.test(profileRequestContext));
         }
         
+        // This is not something SAML supports but we supplement with the local config.
+        authnCtx.setMaxAge(maxAgeLookupStrategy.apply(profileRequestContext));
+        
         // Merge requested and pre-configured proxy count.
         
         final Integer reqCount = authnCtx.getProxyCount();
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java
index cba607b16..dfa097048 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml1/profile/config/impl/BrowserSSOProfileConfiguration.java
@@ -15,6 +15,7 @@
 package net.shibboleth.idp.saml.saml1.profile.config.impl;
 
 import java.security.Principal;
+import java.time.Duration;
 import java.util.Collection;
 import java.util.List;
 import java.util.Set;
@@ -27,7 +28,9 @@ import javax.annotation.Nullable;
 import org.opensaml.profile.context.ProfileRequestContext;
 
 import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.idp.authn.AuthenticationResult;
 import net.shibboleth.idp.authn.config.AuthenticationProfileConfiguration;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
 import net.shibboleth.shared.annotation.constraint.NonNegative;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.annotation.constraint.NotLive;
@@ -63,6 +66,9 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
     
     /** Whether to mandate forced authentication for the request. */
     @Nonnull private Predicate<ProfileRequestContext> forceAuthnPredicate;
+    
+    /** Lookup function for max-age setting. */
+    @Nonnull private Function<ProfileRequestContext,Duration> maxAgeLookupStrategy;
 
     /** Lookup function to supply default authentication methods. */
     @Nonnull private Function<ProfileRequestContext,Collection<Principal>>
@@ -102,6 +108,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
         defaultAuthenticationMethodsLookupStrategy = FunctionSupport.constant(null);
         nameIDFormatPrecedenceLookupStrategy = FunctionSupport.constant(null);
         forceAuthnPredicate = PredicateSupport.alwaysFalse();
+        maxAgeLookupStrategy = FunctionSupport.constant(null);
         proxyCountLookupStrategy = FunctionSupport.constant(null);
     }
 
@@ -244,6 +251,35 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML1AssertionProduc
         forceAuthnPredicate = Constraint.isNotNull(condition, "Forced authentication predicate cannot be null");
     }
 
+    /** {@inheritDoc} */
+    @ConfigurationSetting(name="maxAge")
+    @Nullable public Duration getMaxAge(@Nullable final ProfileRequestContext profileRequestContext) {
+        return maxAgeLookupStrategy.apply(profileRequestContext);
+    }
+    
+    /**
+     * Sets allowed duration between an {@link AuthenticationResult} creation and its reuse for this request.
+     * 
+     * @param maxAge allowed duration
+     * 
+     * @since 5.2.0
+     */
+    public void setMaxAge(@Nullable final Duration maxAge) {
+        maxAgeLookupStrategy = FunctionSupport.constant(maxAge);
+    }
+
+    /**
+     * Sets lookup strategy for the allowed duration between an {@link AuthenticationResult} creation
+     * and its reuse for this request.
+     * 
+     * @param strategy lookup strategy
+     * 
+     * @since 5.2.0
+     */
+    public void setMaxAgeLookupStrategy(@Nonnull final Function<ProfileRequestContext,Duration> strategy) {
+        maxAgeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+    }
+    
     /** {@inheritDoc} */
     @Nonnull @NotLive @Unmodifiable public List<Principal> getDefaultAuthenticationMethods(
             @Nullable final ProfileRequestContext profileRequestContext) {
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
index 672e54440..65ec12775 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/impl/BrowserSSOProfileConfiguration.java
@@ -26,10 +26,12 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import net.shibboleth.idp.attribute.IdPAttribute;
+import net.shibboleth.idp.authn.AuthenticationResult;
 import net.shibboleth.idp.authn.config.AuthenticationProfileConfiguration;
 import net.shibboleth.idp.saml.profile.config.logic.ProxyAwareForceAuthnPredicate;
 import net.shibboleth.idp.saml.saml2.profile.config.navigate.ProxyAwareAuthnContextComparisonLookupFunction;
 import net.shibboleth.idp.saml.saml2.profile.config.navigate.ProxyAwareDefaultAuthenticationMethodsLookupFunction;
+import net.shibboleth.shared.annotation.ConfigurationSetting;
 import net.shibboleth.shared.annotation.constraint.NonNegative;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.annotation.constraint.NotLive;
@@ -75,6 +77,9 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
     /** Whether to mandate forced authentication for the request. */
     @Nonnull private Predicate<ProfileRequestContext> forceAuthnPredicate;
 
+    /** Lookup function for max-age setting. */
+    @Nonnull private Function<ProfileRequestContext,Duration> maxAgeLookupStrategy;
+    
     /** Whether to compare client and assertion addresses on inbound SSO. */
     @Nonnull private Predicate<ProfileRequestContext> checkAddressPredicate;
 
@@ -174,6 +179,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
         includeAttributeStatementPredicate = PredicateSupport.alwaysTrue();
         ignoreScoping = PredicateSupport.alwaysFalse();
         forceAuthnPredicate = new ProxyAwareForceAuthnPredicate();
+        maxAgeLookupStrategy = FunctionSupport.constant(null);
         checkAddressPredicate = PredicateSupport.alwaysTrue();
         checkInResponseToPredicate = PredicateSupport.alwaysTrue();
         skipEndpointValidationWhenSignedPredicate = PredicateSupport.alwaysFalse();
@@ -368,6 +374,35 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2AssertionProduc
         forceAuthnPredicate = Constraint.isNotNull(condition, "Forced authentication predicate cannot be null");
     }
 
+    /** {@inheritDoc} */
+    @ConfigurationSetting(name="maxAge")
+    @Nullable public Duration getMaxAge(@Nullable final ProfileRequestContext profileRequestContext) {
+        return maxAgeLookupStrategy.apply(profileRequestContext);
+    }
+    
+    /**
+     * Sets allowed duration between an {@link AuthenticationResult} creation and its reuse for this request.
+     * 
+     * @param maxAge allowed duration
+     * 
+     * @since 5.2.0
+     */
+    public void setMaxAge(@Nullable final Duration maxAge) {
+        maxAgeLookupStrategy = FunctionSupport.constant(maxAge);
+    }
+
+    /**
+     * Sets lookup strategy for the allowed duration between an {@link AuthenticationResult} creation
+     * and its reuse for this request.
+     * 
+     * @param strategy lookup strategy
+     * 
+     * @since 5.2.0
+     */
+    public void setMaxAgeLookupStrategy(@Nonnull final Function<ProfileRequestContext,Duration> strategy) {
+        maxAgeLookupStrategy = Constraint.isNotNull(strategy, "Lookup strategy cannot be null");
+    }
+    
     /** {@inheritDoc} */
     public boolean isCheckAddress(@Nullable final ProfileRequestContext profileRequestContext) {
         return checkAddressPredicate.test(profileRequestContext);

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


More information about the commits mailing list