[java-identity-provider] branch master updated: JSPT-79 - Review date and time handling for Java 8
Scott Cantor
cantor.2 at osu.edu
Thu Mar 14 11:53:47 EDT 2019
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=73035003021e5fc1db7e6094fbe27020f9c13cf1
The following commit(s) were added to refs/heads/master by this push:
new 7303500 JSPT-79 - Review date and time handling for Java 8
7303500 is described below
commit 73035003021e5fc1db7e6094fbe27020f9c13cf1
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Mar 14 11:53:44 2019 -0400
JSPT-79 - Review date and time handling for Java 8
https://issues.shibboleth.net/jira/browse/JSPT-79
Nearly complete remediation of Duration annotation out of IdP.
Also did some removal of deprecated profile config accessors.
---
.../idp/attribute/impl/JDBCPairwiseIdStore.java | 34 +++---
.../attribute/impl/JDBCPairwiseIdStoreTest.java | 9 +-
.../impl/AbstractExecutableStatementBuilder.java | 22 ++--
.../impl/FormatExecutableStatementBuilder.java | 35 ++----
.../dc/rdbms/impl/RDBMSDataConnectorTest.java | 3 +-
.../dc/ldap/impl/LDAPDataConnectorParser.java | 1 +
.../dc/rdbms/impl/RDBMSDataConnectorParser.java | 20 +---
.../idp/authn/AuthenticationFlowDescriptor.java | 60 ++++++-----
.../idp/authn/context/AuthenticationContext.java | 28 ++---
.../authn/AuthenticationFlowDescriptorTest.java | 23 ++--
.../idp/authn/impl/FilterFlowsByForcedAuthn.java | 2 +-
.../PopulateMultiFactorAuthenticationContext.java | 4 +-
.../impl/TransitionMultiFactorAuthentication.java | 2 +-
.../authn/impl/FilterFlowsByForceAuthnTest.java | 5 +-
...pulateMultiFactorAuthenticationContextTest.java | 11 +-
.../config/impl/AbstractProtocolConfiguration.java | 48 ++++-----
.../idp/cas/config/impl/LoginConfiguration.java | 2 -
.../idp/cas/config/impl/ProxyConfiguration.java | 2 -
.../idp/cas/config/impl/ValidateConfiguration.java | 5 +-
.../idp/cas/flow/impl/GrantProxyTicketAction.java | 2 +-
.../cas/flow/impl/GrantServiceTicketAction.java | 2 +-
.../cas/flow/impl/ValidateProxyCallbackAction.java | 2 +-
.../impl/AbstractConsentIndexedStorageAction.java | 9 +-
.../storage/impl/CreateGlobalConsentResult.java | 2 +-
.../consent/flow/storage/impl/CreateResult.java | 2 +-
.../idp/consent/storage/impl/ConsentResult.java | 6 +-
.../idp/profile/config/SecurityConfiguration.java | 24 ++---
.../AbstractProfileInterceptorResult.java | 23 ++--
.../interceptor/ProfileInterceptorResult.java | 8 +-
.../idp/profile/logic/DateAttributePredicate.java | 13 ---
.../AbstractProfileInterceptorResultTest.java | 26 ++---
.../WriteProfileInterceptorResultToStorage.java | 8 +-
...WriteProfileInterceptorResultToStorageTest.java | 12 +--
.../config/AbstractSAMLProfileConfiguration.java | 53 ++++-----
.../DurationConfigurationLookupStrategy.java | 20 ++--
.../profile/config/SAMLProfileConfiguration.java | 8 +-
.../navigate/AssertionLifetimeLookupFunction.java | 2 +-
.../navigate/SessionLifetimeLookupFunction.java | 6 +-
.../config/BrowserSSOProfileConfiguration.java | 118 +++------------------
.../AbstractSAMLProfileConfigurationTest.java | 25 ++---
.../config/BrowserSSOProfileConfigurationTest.java | 60 ++++-------
.../impl/StoredTransientIdGenerationStrategy.java | 31 +++---
.../profile/impl/AddAuthnStatementToAssertion.java | 11 +-
.../impl/PopulateDelegationContextTest.java | 20 ----
.../impl/AddAuthnStatementToAssertionTest.java | 3 +-
.../impl/ExtractActiveAuthenticationResults.java | 5 +-
.../idp/session/impl/StorageBackedIdPSession.java | 12 +--
.../impl/StorageBackedSessionManagerTest.java | 8 +-
48 files changed, 339 insertions(+), 498 deletions(-)
diff --git a/idp-attribute-impl/src/main/java/net/shibboleth/idp/attribute/impl/JDBCPairwiseIdStore.java b/idp-attribute-impl/src/main/java/net/shibboleth/idp/attribute/impl/JDBCPairwiseIdStore.java
index dd44c7f..cacc4fb 100644
--- a/idp-attribute-impl/src/main/java/net/shibboleth/idp/attribute/impl/JDBCPairwiseIdStore.java
+++ b/idp-attribute-impl/src/main/java/net/shibboleth/idp/attribute/impl/JDBCPairwiseIdStore.java
@@ -24,6 +24,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -37,7 +38,6 @@ import javax.sql.DataSource;
import net.shibboleth.idp.attribute.DurablePairwiseIdStore;
import net.shibboleth.idp.attribute.PairwiseId;
import net.shibboleth.idp.attribute.PairwiseIdStore;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.Live;
import net.shibboleth.utilities.java.support.annotation.constraint.NonNegative;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
@@ -83,8 +83,8 @@ public class JDBCPairwiseIdStore extends AbstractInitializableComponent implemen
/** JDBC data source for retrieving connections. */
@NonnullAfterInit private DataSource dataSource;
- /** Timeout of SQL queries in milliseconds. */
- @Duration @NonNegative private long queryTimeout;
+ /** Timeout of SQL queries. */
+ @Nonnull private Duration queryTimeout;
/** Number of times to retry a transaction if it rolls back. */
@NonNegative private int transactionRetry;
@@ -147,7 +147,7 @@ public class JDBCPairwiseIdStore extends AbstractInitializableComponent implemen
public JDBCPairwiseIdStore() {
transactionRetry = 3;
retryableErrors = Arrays.asList("23000", "23505");
- queryTimeout = 5000;
+ queryTimeout = Duration.ofSeconds(5);
verifyDatabase = true;
tableName = "shibpid";
@@ -184,21 +184,23 @@ public class JDBCPairwiseIdStore extends AbstractInitializableComponent implemen
/**
* Get the SQL query timeout.
*
- * @return the timeout in milliseconds
+ * @return the timeout
*/
- @NonNegative @Duration public long getQueryTimeout() {
+ @Nonnull public Duration getQueryTimeout() {
return queryTimeout;
}
/**
- * Set the SQL query timeout. Defaults to 5000.
+ * Set the SQL query timeout. Defaults to 5s.
*
- * @param timeout the timeout to set in milliseconds
+ * @param timeout the timeout to set
*/
- @Duration public void setQueryTimeout(@Duration @NonNegative final long timeout) {
+ public void setQueryTimeout(@Nonnull final Duration timeout) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ Constraint.isNotNull(timeout, "Timeout cannot be null");
+ Constraint.isFalse(timeout.isNegative(), "Timeout cannot be negative");
- queryTimeout = Constraint.isGreaterThanOrEqual(0, timeout, "Timeout must be greater than or equal to 0");
+ queryTimeout = timeout;
}
/**
@@ -557,7 +559,7 @@ public class JDBCPairwiseIdStore extends AbstractInitializableComponent implemen
while (true) {
try (final Connection dbConn = getConnection(false)) {
final PreparedStatement statement = dbConn.prepareStatement(getBySourceSelectSQL);
- statement.setQueryTimeout((int) (queryTimeout / 1000));
+ statement.setQueryTimeout((int) queryTimeout.toSeconds());
statement.setString(1, pid.getIssuerEntityID());
statement.setString(2, pid.getRecipientEntityID());
statement.setString(3, pid.getSourceSystemId());
@@ -638,7 +640,7 @@ public class JDBCPairwiseIdStore extends AbstractInitializableComponent implemen
try (final Connection dbConn = getConnection(true)) {
final PreparedStatement statement = dbConn.prepareStatement(getByIssuedSelectSQL);
- statement.setQueryTimeout((int) (queryTimeout / 1000));
+ statement.setQueryTimeout((int) queryTimeout.toSeconds());
statement.setString(1, pid.getIssuerEntityID());
statement.setString(2, pid.getRecipientEntityID());
@@ -685,7 +687,7 @@ public class JDBCPairwiseIdStore extends AbstractInitializableComponent implemen
try (final Connection dbConn = getConnection(true)) {
final PreparedStatement statement = dbConn.prepareStatement(deactivateSQL);
- statement.setQueryTimeout((int) (queryTimeout / 1000));
+ statement.setQueryTimeout((int) queryTimeout.toSeconds());
statement.setTimestamp(1, deactivationTime);
statement.setString(2, pid.getIssuerEntityID());
statement.setString(3, pid.getRecipientEntityID());
@@ -719,7 +721,7 @@ public class JDBCPairwiseIdStore extends AbstractInitializableComponent implemen
try (final Connection dbConn = getConnection(true)) {
final PreparedStatement statement = dbConn.prepareStatement(attachSQL);
- statement.setQueryTimeout((int) (queryTimeout / 1000));
+ statement.setQueryTimeout((int) queryTimeout.toSeconds());
statement.setString(1, pid.getPeerProvidedId());
statement.setString(2, pid.getIssuerEntityID());
statement.setString(3, pid.getRecipientEntityID());
@@ -767,7 +769,7 @@ public class JDBCPairwiseIdStore extends AbstractInitializableComponent implemen
log.trace("Setting prepared statement parameter {}: {}", 8, entry.getDeactivationTime());
final PreparedStatement statement = dbConn.prepareStatement(insertSQL);
- statement.setQueryTimeout((int) (queryTimeout / 1000));
+ statement.setQueryTimeout((int) queryTimeout.toSeconds());
statement.setString(1, entry.getIssuerEntityID());
statement.setString(2, entry.getRecipientEntityID());
@@ -840,7 +842,7 @@ public class JDBCPairwiseIdStore extends AbstractInitializableComponent implemen
try (final Connection conn = getConnection(true)) {
final PreparedStatement statement = conn.prepareStatement(deleteSQL);
- statement.setQueryTimeout((int) (queryTimeout / 1000));
+ statement.setQueryTimeout((int) queryTimeout.toSeconds());
statement.setString(1, "http://dummy.com/idp/" + uuid);
statement.executeUpdate();
}
diff --git a/idp-attribute-impl/src/test/java/net/shibboleth/idp/attribute/impl/JDBCPairwiseIdStoreTest.java b/idp-attribute-impl/src/test/java/net/shibboleth/idp/attribute/impl/JDBCPairwiseIdStoreTest.java
index a6b5ac8..8af5473 100644
--- a/idp-attribute-impl/src/test/java/net/shibboleth/idp/attribute/impl/JDBCPairwiseIdStoreTest.java
+++ b/idp-attribute-impl/src/test/java/net/shibboleth/idp/attribute/impl/JDBCPairwiseIdStoreTest.java
@@ -20,6 +20,7 @@ package net.shibboleth.idp.attribute.impl;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
+import java.time.Duration;
import java.util.Objects;
import java.util.UUID;
@@ -67,8 +68,8 @@ public class JDBCPairwiseIdStoreTest {
store.setDataSource(testSource);
Assert.assertEquals(store.getDataSource(), testSource);
- Assert.assertEquals(store.getQueryTimeout(), 5000);
- store.setQueryTimeout(1);
+ Assert.assertEquals(store.getQueryTimeout(), Duration.ofSeconds(5));
+ store.setQueryTimeout(Duration.ofMillis(1));
try {
store.getBySourceValue(new PairwiseId(), true);
@@ -86,13 +87,13 @@ public class JDBCPairwiseIdStoreTest {
}
store.initialize();
try {
- store.setQueryTimeout(0);
+ store.setQueryTimeout(Duration.ZERO);
Assert.fail("work after initialize");
} catch (final UnmodifiableComponentException e) {
// OK
}
Assert.assertEquals(store.getDataSource(), testSource);
- Assert.assertEquals(store.getQueryTimeout(), 1);
+ Assert.assertEquals(store.getQueryTimeout(), Duration.ofMillis(1));
}
private boolean comparePersistentIdEntrys(@Nonnull PairwiseId one, @Nonnull PairwiseId other)
diff --git a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/AbstractExecutableStatementBuilder.java b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/AbstractExecutableStatementBuilder.java
index 260b9ba..579aeb8 100644
--- a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/AbstractExecutableStatementBuilder.java
+++ b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/AbstractExecutableStatementBuilder.java
@@ -21,6 +21,7 @@ import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.time.Duration;
import java.util.List;
import java.util.Map;
@@ -33,6 +34,7 @@ import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
import net.shibboleth.idp.attribute.resolver.dc.impl.ExecutableSearchBuilder;
import net.shibboleth.utilities.java.support.component.AbstractInitializableComponent;
import net.shibboleth.utilities.java.support.component.ComponentSupport;
+import net.shibboleth.utilities.java.support.logic.Constraint;
/**
* Basis of statement builder. The derived classes just have to provide the per request sql string.
@@ -41,24 +43,32 @@ public abstract class AbstractExecutableStatementBuilder extends AbstractInitial
ExecutableSearchBuilder<ExecutableStatement> {
/** Query timeout. */
- private int queryTimeout = 5000;
+ @Nonnull private Duration queryTimeout;
+ /** Constructor. */
+ public AbstractExecutableStatementBuilder() {
+ queryTimeout = Duration.ofSeconds(5);
+ }
+
/**
* Gets the timeout of the SQL query.
*
- * @return timeout of the SQL query in seconds
+ * @return timeout of the SQL query
*/
- public int getQueryTimeout() {
+ @Nonnull public Duration getQueryTimeout() {
return queryTimeout;
}
/**
* Sets the timeout of the SQL query.
*
- * @param timeout of the SQL query in seconds
+ * @param timeout of the SQL query
*/
- public void setQueryTimeout(final int timeout) {
+ public void setQueryTimeout(@Nonnull final Duration timeout) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ Constraint.isNotNull(timeout, "Query timeout cannot be null");
+ Constraint.isFalse(timeout.isNegative(), "Query timeout cannot be negative");
+
queryTimeout = timeout;
}
@@ -89,7 +99,7 @@ public abstract class AbstractExecutableStatementBuilder extends AbstractInitial
/** {@inheritDoc} */
@Nonnull public ResultSet execute(@Nonnull final Connection connection) throws SQLException {
final Statement stmt = connection.createStatement();
- stmt.setQueryTimeout(queryTimeout);
+ stmt.setQueryTimeout((int) queryTimeout.toSeconds());
return stmt.executeQuery(query);
}
diff --git a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/FormatExecutableStatementBuilder.java b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/FormatExecutableStatementBuilder.java
index 55945f1..1a38581 100644
--- a/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/FormatExecutableStatementBuilder.java
+++ b/idp-attribute-resolver-impl/src/main/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/FormatExecutableStatementBuilder.java
@@ -25,6 +25,7 @@ import javax.annotation.Nonnull;
import net.shibboleth.idp.attribute.IdPAttributeValue;
import net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.logic.Constraint;
@@ -36,40 +37,24 @@ import net.shibboleth.utilities.java.support.logic.Constraint;
public class FormatExecutableStatementBuilder extends AbstractExecutableStatementBuilder {
/** SQL query string. */
- private String sqlQuery;
-
- /**
- * Constructor.
+ @NonnullAfterInit private String sqlQuery;
+
+ /** Set the query to search the database.
+ * @param query query to search the database
*/
- public FormatExecutableStatementBuilder() {
+ public void setQuery(@Nonnull final String query) {
+ sqlQuery = Constraint.isNotNull(query, "SQL query cannot be null");
}
/** {@inheritDoc} */
@Override
protected void doInitialize() throws ComponentInitializationException {
+ super.doInitialize();
+
if (null == sqlQuery) {
throw new ComponentInitializationException(
- "FormatExecutableStatementBuilder: SQL query can not be null");
- }
- if (getQueryTimeout() <= 0) {
- throw new ComponentInitializationException(
- "FormatExecutableStatementBuilder: Query timeout must be greater than zero");
+ "FormatExecutableStatementBuilder: SQL query cannot be null");
}
- super.doInitialize();
- }
-
- /** Set the query to search the database.
- * @param query query to search the database
- */
- public void setQuery(@Nonnull final String query) {
- sqlQuery = Constraint.isNotNull(query, "SQL query can not be null");
- }
-
- /** Set the search timeout.
- * @param timeout search timeout
- */
- public void setTimeOut(@Nonnull final int timeout) {
- setQueryTimeout((int) Constraint.isGreaterThanOrEqual(0, timeout, "Query timeout must be greater than zero"));
}
/** {@inheritDoc} */
diff --git a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/RDBMSDataConnectorTest.java b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/RDBMSDataConnectorTest.java
index ce8a1a6..32935a4 100644
--- a/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/RDBMSDataConnectorTest.java
+++ b/idp-attribute-resolver-impl/src/test/java/net/shibboleth/idp/attribute/resolver/dc/rdbms/impl/RDBMSDataConnectorTest.java
@@ -18,6 +18,7 @@
package net.shibboleth.idp.attribute.resolver.dc.rdbms.impl;
import java.sql.SQLException;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -393,7 +394,7 @@ public class RDBMSDataConnectorTest {
return builder;
}
- static protected FormatExecutableStatementBuilder newFormatExecutableStatementBuilder(@Nonnull final String query, @Nonnull final int timeout) {
+ static protected FormatExecutableStatementBuilder newFormatExecutableStatementBuilder(@Nonnull final String query, @Nonnull final Duration timeout) {
final FormatExecutableStatementBuilder builder = new FormatExecutableStatementBuilder();
builder.setQuery(query);
builder.setQueryTimeout(timeout);
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/impl/LDAPDataConnectorParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/impl/LDAPDataConnectorParser.java
index 27fae5b..a5d2dee 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/impl/LDAPDataConnectorParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/ldap/impl/LDAPDataConnectorParser.java
@@ -640,6 +640,7 @@ public class LDAPDataConnectorParser extends AbstractDataConnectorParser {
final BeanDefinitionBuilder period =
BeanDefinitionBuilder.rootBeanDefinition(V2Parser.class, "buildDuration");
period.addConstructorArgValue(validateTimerPeriod);
+ // Convert to seconds.
period.addConstructorArgValue(1000);
poolConfig.addPropertyValue("validatePeriod", period.getBeanDefinition());
} else {
diff --git a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/rdbms/impl/RDBMSDataConnectorParser.java b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/rdbms/impl/RDBMSDataConnectorParser.java
index 5bd9ff9..bbc5fa3 100644
--- a/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/rdbms/impl/RDBMSDataConnectorParser.java
+++ b/idp-attribute-resolver-spring/src/main/java/net/shibboleth/idp/attribute/resolver/spring/dc/rdbms/impl/RDBMSDataConnectorParser.java
@@ -39,7 +39,6 @@ import net.shibboleth.idp.attribute.resolver.spring.dc.AbstractDataConnectorPars
import net.shibboleth.idp.attribute.resolver.spring.dc.impl.CacheConfigParser;
import net.shibboleth.idp.attribute.resolver.spring.dc.impl.ManagedConnectionParser;
import net.shibboleth.idp.attribute.resolver.spring.impl.AttributeResolverNamespaceHandler;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.primitive.StringSupport;
@@ -203,11 +202,7 @@ public class RDBMSDataConnectorParser extends AbstractDataConnectorParser {
final String queryTimeout = AttributeSupport.getAttributeValue(configElement, new QName("queryTimeout"));
if (queryTimeout != null) {
- final BeanDefinitionBuilder duration =
- BeanDefinitionBuilder.rootBeanDefinition(V2Parser.class, "buildDuration");
- duration.addConstructorArgValue(queryTimeout);
- duration.addConstructorArgValue(1);
- templateBuilder.addPropertyValue("queryTimeout", duration.getBeanDefinition());
+ templateBuilder.addPropertyValue("queryTimeout", queryTimeout);
}
final List<Element> queryTemplates = ElementSupport.getChildElementsByTagNameNS(configElement,
@@ -331,19 +326,6 @@ public class RDBMSDataConnectorParser extends AbstractDataConnectorParser {
@Nonnull @NotEmpty private String getLogPrefix() {
return logPrefix;
}
-
- /**
- * Converts the supplied duration to milliseconds and divides it by the divisor. Useful for modifying durations
- * while resolving property replacement.
- *
- * @param duration the duration (which may have gone through spring translation from iso to long)
- * @param divisor to modify the duration with
- *
- * @return result of the division
- */
- @Duration public static long buildDuration(@Duration final long duration, final long divisor) {
- return duration / divisor;
- }
}
}
\ No newline at end of file
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptor.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptor.java
index c861c61..c06cd87 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptor.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptor.java
@@ -19,6 +19,8 @@ package net.shibboleth.idp.authn;
import java.io.IOException;
import java.security.Principal;
+import java.time.Duration;
+import java.time.Instant;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -33,11 +35,8 @@ import javax.security.auth.Subject;
import net.shibboleth.idp.authn.principal.PrincipalSupportingComponent;
import net.shibboleth.idp.profile.FlowDescriptor;
-import net.shibboleth.utilities.java.support.annotation.Duration;
-import net.shibboleth.utilities.java.support.annotation.constraint.NonNegative;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
import net.shibboleth.utilities.java.support.component.AbstractIdentifiableInitializableComponent;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
@@ -68,7 +67,7 @@ public class AuthenticationFlowDescriptor extends AbstractIdentifiableInitializa
@Nonnull @NotEmpty public static final String FLOW_ID_PREFIX = "authn/";
/** Additional allowance for storage of result records to avoid race conditions during use. */
- public static final long STORAGE_EXPIRATION_OFFSET;
+ @Nonnull public static final Duration STORAGE_EXPIRATION_OFFSET;
/** Whether this flow supports non-browser clients. */
private boolean supportsNonBrowser;
@@ -82,11 +81,11 @@ public class AuthenticationFlowDescriptor extends AbstractIdentifiableInitializa
/** Whether this flow allows reuse of its results. */
@Nonnull private Predicate<ProfileRequestContext> reuseCondition;
- /** Maximum amount of time in milliseconds, since first usage, a flow should be considered active. */
- @Duration @NonNegative private long lifetime;
+ /** Maximum amount of time since first usage that a flow should be considered active. */
+ @Nullable private Duration lifetime;
- /** Maximum amount of time in milliseconds, since last usage, a flow should be considered active. */
- @Duration @Positive private long inactivityTimeout;
+ /** Maximum amount of time since last usage that a flow should be considered active. */
+ @Nonnull private Duration inactivityTimeout;
/**
* Supported principals, indexed by type, that the flow can produce. Implemented for the moment using the Subject
@@ -109,7 +108,7 @@ public class AuthenticationFlowDescriptor extends AbstractIdentifiableInitializa
reuseCondition = Predicates.alwaysTrue();
supportedPrincipals = new Subject();
activationCondition = Predicates.alwaysTrue();
- inactivityTimeout = 30 * 60 * 1000;
+ inactivityTimeout = Duration.ofMinutes(30);
principalWeightMap = Collections.emptyMap();
}
@@ -200,29 +199,31 @@ public class AuthenticationFlowDescriptor extends AbstractIdentifiableInitializa
}
/**
- * Get the maximum amount of time in milliseconds, since first usage, a flow should be considered active. A value
- * of 0 indicates that there is no upper limit on the lifetime on an active flow.
+ * Get the maximum amount of time, since first usage, a flow should be considered active. A null
+ * indicates that there is no upper limit on the lifetime on an active flow.
*
- * @return maximum amount of time in milliseconds a flow should be considered active, never less than 0
+ * @return maximum amount of time a flow should be considered active
*/
- @NonNegative @Duration public long getLifetime() {
+ @Nullable public Duration getLifetime() {
return lifetime;
}
/**
- * Set the maximum amount of time in milliseconds, since first usage, a flow should be considered active. A value
- * of 0 indicates that there is no upper limit on the lifetime on an active flow.
+ * Set the maximum amount of time, since first usage, a flow should be considered active. A null value
+ * indicates that there is no upper limit on the lifetime on an active flow.
*
- * @param flowLifetime the lifetime for the flow, must be 0 or greater
+ * @param flowLifetime the lifetime for the flow
*/
- @Duration public void setLifetime(@Duration @NonNegative final long flowLifetime) {
+ public void setLifetime(@Nullable final Duration flowLifetime) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ Constraint.isFalse(flowLifetime != null && (flowLifetime.isNegative() || flowLifetime.isZero()),
+ "Lifetime must be null or greater than 0");
- lifetime = Constraint.isGreaterThanOrEqual(0, flowLifetime, "Lifetime must be greater than or equal to 0");
+ lifetime = flowLifetime;
}
/**
- * Get the maximum amount of time in milliseconds, since the last usage, a flow should be considered active.
+ * Get the maximum amount of time, since the last usage, a flow should be considered active.
*
* <p>
* Defaults to 30 minutes.
@@ -230,19 +231,21 @@ public class AuthenticationFlowDescriptor extends AbstractIdentifiableInitializa
*
* @return the duration
*/
- @Duration @Positive public long getInactivityTimeout() {
+ @Nonnull public Duration getInactivityTimeout() {
return inactivityTimeout;
}
/**
- * Set the maximum amount of time in milliseconds, since the last usage, a flow should be considered active.
+ * Set the maximum amount of time, since the last usage, a flow should be considered active.
*
* @param timeout the flow inactivity timeout, must be greater than zero
*/
- @Duration public void setInactivityTimeout(@Duration @Positive final long timeout) {
+ public void setInactivityTimeout(@Nonnull final Duration timeout) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+ Constraint.isNotNull(timeout, "Inactivity timeout cannot be null");
+ Constraint.isFalse(timeout.isNegative() || timeout.isZero(), "Inactivity timeout must be greater than 0");
- inactivityTimeout = Constraint.isGreaterThan(0, timeout, "Inactivity timeout must be greater than 0");
+ inactivityTimeout = timeout;
}
/**
@@ -257,11 +260,10 @@ public class AuthenticationFlowDescriptor extends AbstractIdentifiableInitializa
Constraint.isTrue(result.getAuthenticationFlowId().equals(getId()),
"AuthenticationResult was not produced by this flow");
- final long now = System.currentTimeMillis();
- if (getLifetime() > 0 && result.getAuthenticationInstant().plusMillis(getLifetime()).toEpochMilli() <= now) {
+ final Instant now = Instant.now();
+ if (getLifetime() != null && now.isAfter(result.getAuthenticationInstant().plus(getLifetime()))) {
return false;
- } else if (getInactivityTimeout() > 0
- && result.getLastActivityInstant().plusMillis(getInactivityTimeout()).toEpochMilli() <= now) {
+ } else if (now.isAfter(result.getLastActivityInstant().plus(getInactivityTimeout()))) {
return false;
}
@@ -370,7 +372,7 @@ public class AuthenticationFlowDescriptor extends AbstractIdentifiableInitializa
// Back the expiration off by the inactivity timeout to recover the last activity time.
return resultSerializer.deserialize(version, context, key, value, (expiration != null) ? expiration
- - inactivityTimeout - STORAGE_EXPIRATION_OFFSET : null);
+ - inactivityTimeout.toMillis() - STORAGE_EXPIRATION_OFFSET.toMillis() : null);
}
/**
@@ -448,6 +450,6 @@ public class AuthenticationFlowDescriptor extends AbstractIdentifiableInitializa
}
static {
- STORAGE_EXPIRATION_OFFSET = 10 * 60 * 1000;
+ STORAGE_EXPIRATION_OFFSET = Duration.ofMinutes(10);
}
}
\ No newline at end of file
diff --git a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationContext.java b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationContext.java
index db9378b..7bc299d 100644
--- a/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationContext.java
+++ b/idp-authn-api/src/main/java/net/shibboleth/idp/authn/context/AuthenticationContext.java
@@ -19,6 +19,7 @@ package net.shibboleth.idp.authn.context;
import java.lang.reflect.Constructor;
import java.security.Principal;
+import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
@@ -36,9 +37,7 @@ import net.shibboleth.idp.authn.AuthenticationResult;
import net.shibboleth.idp.authn.AuthenticationFlowDescriptor;
import net.shibboleth.idp.authn.principal.PrincipalEvalPredicateFactoryRegistry;
import net.shibboleth.idp.authn.principal.PrincipalSupportingComponent;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.Live;
-import net.shibboleth.utilities.java.support.annotation.constraint.NonNegative;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.logic.Constraint;
@@ -78,8 +77,8 @@ public final class AuthenticationContext extends BaseContext {
/** A non-normative hint some protocols support to indicate who the subject might be. */
@Nullable private String hintedName;
- /** Allowed time in ms since an {@link AuthenticationResult} was created that it can be reused for this request. */
- @NonNegative @Duration private long maxAge;
+ /** Allowed time since an {@link AuthenticationResult} was created that it can be reused for this request. */
+ @Nullable private Duration maxAge;
/** Lookup strategy for a fixed event to return from validators for testing. */
@Nullable private Function<ProfileRequestContext,String> fixedEventLookupStrategy;
@@ -330,33 +329,36 @@ public final class AuthenticationContext extends BaseContext {
}
/**
- * Get duration in milliseconds since an {@link AuthenticationResult} was created that
+ * Get duration since an {@link AuthenticationResult} was created that
* allows it to be reused for this request.
*
- * <p>If zero, no constraint is applied.</p>
+ * <p>If null, no constraint is applied.</p>
*
- * @return duration in milliseconds, or zero
+ * @return duration
*
* @since 3.4.0
*/
- @NonNegative @Duration public long getMaxAge() {
+ @Nullable public Duration getMaxAge() {
return maxAge;
}
/**
- * Set duration in milliseconds since an {@link AuthenticationResult} was created that
+ * Set duration since an {@link AuthenticationResult} was created that
* allows it to be reused for this request.
*
- * <p>Set to zero to apply no constraint.</p>
+ * <p>Set to null to apply no constraint.</p>
*
- * @param age duration in milliseconds, or zero
+ * @param age duration
*
* @return this context
*
* @since 3.4.0
*/
- @Nonnull public AuthenticationContext setMaxAge(@NonNegative @Duration final long age) {
- maxAge = Constraint.isGreaterThanOrEqual(0, age, "MaxAge cannot be negative");
+ @Nonnull public AuthenticationContext setMaxAge(@Nullable final Duration age) {
+
+ Constraint.isFalse(age != null && (age.isNegative() || age.isZero()), "MaxAge must be null or greater than 0");
+
+ maxAge = age;
return this;
}
diff --git a/idp-authn-api/src/test/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptorTest.java b/idp-authn-api/src/test/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptorTest.java
index 5e66ea7..0216314 100644
--- a/idp-authn-api/src/test/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptorTest.java
+++ b/idp-authn-api/src/test/java/net/shibboleth/idp/authn/AuthenticationFlowDescriptorTest.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.authn;
+import java.time.Duration;
import java.util.Arrays;
import net.shibboleth.idp.authn.principal.UsernamePrincipal;
@@ -46,27 +47,27 @@ public class AuthenticationFlowDescriptorTest {
/** Tests mutating lifetime. */
@Test public void testLifetime() {
- descriptor.setLifetime(10);
- Assert.assertEquals(descriptor.getLifetime(), 10);
+ descriptor.setLifetime(Duration.ofMillis(10));
+ Assert.assertEquals(descriptor.getLifetime(), Duration.ofMillis(10));
try {
- descriptor.setLifetime(-10);
+ descriptor.setLifetime(Duration.ofMillis(-10));
Assert.fail();
} catch (ConstraintViolationException e) {
- Assert.assertEquals(descriptor.getLifetime(), 10);
+ Assert.assertEquals(descriptor.getLifetime(), Duration.ofMillis(10));
}
}
/** Tests mutating inactivity timeout. */
@Test public void testInactivityTimeout() {
- descriptor.setInactivityTimeout(10);
- Assert.assertEquals(descriptor.getInactivityTimeout(), 10);
+ descriptor.setInactivityTimeout(Duration.ofMillis(10));
+ Assert.assertEquals(descriptor.getInactivityTimeout(), Duration.ofMillis(10));
try {
- descriptor.setInactivityTimeout(-10);
+ descriptor.setInactivityTimeout(Duration.ofMillis(-10));
Assert.fail();
} catch (ConstraintViolationException e) {
- Assert.assertEquals(descriptor.getInactivityTimeout(), 10);
+ Assert.assertEquals(descriptor.getInactivityTimeout(), Duration.ofMillis(10));
}
}
@@ -126,15 +127,15 @@ public class AuthenticationFlowDescriptorTest {
Thread.sleep(20);
- descriptor.setLifetime(10);
+ descriptor.setLifetime(Duration.ofMillis(10));
Assert.assertFalse(descriptor.isResultActive(result));
- descriptor.setLifetime(5000);
+ descriptor.setLifetime(Duration.ofSeconds(5));
Assert.assertTrue(descriptor.isResultActive(result));
Thread.sleep(20);
- descriptor.setInactivityTimeout(10);
+ descriptor.setInactivityTimeout(Duration.ofMillis(10));
Assert.assertFalse(descriptor.isResultActive(result));
result.setLastActivityInstantToNow();
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/FilterFlowsByForcedAuthn.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/FilterFlowsByForcedAuthn.java
index 40609ad..79cfe4d 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/FilterFlowsByForcedAuthn.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/FilterFlowsByForcedAuthn.java
@@ -49,7 +49,7 @@ public class FilterFlowsByForcedAuthn extends AbstractAuthenticationAction {
protected boolean doPreExecute(@Nonnull final ProfileRequestContext profileRequestContext,
@Nonnull final AuthenticationContext authenticationContext) {
- if (!authenticationContext.isForceAuthn() && authenticationContext.getMaxAge() == 0) {
+ if (!authenticationContext.isForceAuthn() && authenticationContext.getMaxAge() == null) {
log.debug("{} Request does not have forced authentication requirement, nothing to do", getLogPrefix());
return false;
}
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/PopulateMultiFactorAuthenticationContext.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/PopulateMultiFactorAuthenticationContext.java
index abaae08..f549e5c 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/PopulateMultiFactorAuthenticationContext.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/PopulateMultiFactorAuthenticationContext.java
@@ -231,8 +231,8 @@ public class PopulateMultiFactorAuthenticationContext extends AbstractAuthentica
if (descriptor != null) {
if (descriptor.test(profileRequestContext)) {
if (descriptor.isResultActive(candidate)) {
- if (authenticationContext.getMaxAge() > 0
- && candidate.getAuthenticationInstant().plusMillis(
+ if (authenticationContext.getMaxAge() != null
+ && candidate.getAuthenticationInstant().plus(
authenticationContext.getMaxAge()).isBefore(Instant.now())) {
log.debug("{} Ignoring active result from login flow {} due to maxAge on request",
getLogPrefix(), candidate.getAuthenticationFlowId());
diff --git a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/TransitionMultiFactorAuthentication.java b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/TransitionMultiFactorAuthentication.java
index 9e045db..8916ba7 100644
--- a/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/TransitionMultiFactorAuthentication.java
+++ b/idp-authn-impl/src/main/java/net/shibboleth/idp/authn/impl/TransitionMultiFactorAuthentication.java
@@ -284,7 +284,7 @@ public class TransitionMultiFactorAuthentication extends AbstractAuthenticationA
getLogPrefix(), flowId);
ActionSupport.buildEvent(profileRequestContext, AuthnEventIds.NO_PASSIVE);
return;
- } else if ((authenticationContext.isForceAuthn() || authenticationContext.getMaxAge() > 0)
+ } else if ((authenticationContext.isForceAuthn() || authenticationContext.getMaxAge() != null)
&& !flow.isForcedAuthenticationSupported()) {
log.error("{} Targeted login flow '{}' does not support forced re-authentication",
getLogPrefix(), flowId);
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/FilterFlowsByForceAuthnTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/FilterFlowsByForceAuthnTest.java
index 4c09972..042b561 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/FilterFlowsByForceAuthnTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/FilterFlowsByForceAuthnTest.java
@@ -21,6 +21,8 @@ import net.shibboleth.idp.authn.AuthenticationFlowDescriptor;
import net.shibboleth.idp.authn.context.AuthenticationContext;
import net.shibboleth.idp.profile.ActionTestingSupport;
+import java.time.Duration;
+
import org.springframework.webflow.execution.Event;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
@@ -41,7 +43,6 @@ public class FilterFlowsByForceAuthnTest extends BaseAuthenticationContextTest {
@Test public void testNonForced() throws Exception {
final AuthenticationContext authCtx = prc.getSubcontext(AuthenticationContext.class);
authCtx.setForceAuthn(false);
- authCtx.setMaxAge(0);
final Event event = action.execute(src);
ActionTestingSupport.assertProceedEvent(event);
@@ -62,7 +63,7 @@ public class FilterFlowsByForceAuthnTest extends BaseAuthenticationContextTest {
@Test public void testPartialFiltering() {
final AuthenticationContext authCtx = prc.getSubcontext(AuthenticationContext.class);
- authCtx.setMaxAge(3600 * 1000);
+ authCtx.setMaxAge(Duration.ofHours(1));
authCtx.getPotentialFlows().get("test2").setForcedAuthenticationSupported(true);
final Event event = action.execute(src);
diff --git a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/PopulateMultiFactorAuthenticationContextTest.java b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/PopulateMultiFactorAuthenticationContextTest.java
index 27ee20d..0c0162c 100644
--- a/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/PopulateMultiFactorAuthenticationContextTest.java
+++ b/idp-authn-impl/src/test/java/net/shibboleth/idp/authn/impl/PopulateMultiFactorAuthenticationContextTest.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.authn.impl;
+import java.time.Duration;
import java.time.Instant;
import java.util.Collections;
import java.util.Map;
@@ -109,32 +110,32 @@ public class PopulateMultiFactorAuthenticationContextTest {
AuthenticationFlowDescriptor desc = new AuthenticationFlowDescriptor();
desc.setId("foo");
desc.setResultSerializer(new DefaultAuthenticationResultSerializer());
- desc.setLifetime(3600 * 1000);
+ desc.setLifetime(Duration.ofHours(1));
desc.initialize();
ac.getAvailableFlows().put(desc.getId(), desc);
desc = new AuthenticationFlowDescriptor();
desc.setId("bar");
desc.setResultSerializer(new DefaultAuthenticationResultSerializer());
- desc.setLifetime(3600 * 1000);
+ desc.setLifetime(Duration.ofHours(1));
desc.initialize();
ac.getAvailableFlows().put(desc.getId(), desc);
desc = new AuthenticationFlowDescriptor();
desc.setId("bav");
desc.setResultSerializer(new DefaultAuthenticationResultSerializer());
- desc.setLifetime(3600 * 1000);
+ desc.setLifetime(Duration.ofHours(1));
desc.initialize();
ac.getAvailableFlows().put(desc.getId(), desc);
desc = new AuthenticationFlowDescriptor();
desc.setId("bag");
desc.setResultSerializer(new DefaultAuthenticationResultSerializer());
- desc.setLifetime(3600 * 1000);
+ desc.setLifetime(Duration.ofHours(1));
desc.initialize();
ac.getAvailableFlows().put(desc.getId(), desc);
- ac.setMaxAge(1800 * 1000);
+ ac.setMaxAge(Duration.ofMinutes(30));
action.setTransitionMapLookupStrategy(
FunctionSupport.<ProfileRequestContext,Map<String,MultiFactorAuthenticationTransition>>constant(
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/AbstractProtocolConfiguration.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/AbstractProtocolConfiguration.java
index 02a84eb..57bb661 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/AbstractProtocolConfiguration.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/AbstractProtocolConfiguration.java
@@ -17,7 +17,7 @@
package net.shibboleth.idp.cas.config.impl;
-import java.util.concurrent.TimeUnit;
+import java.time.Duration;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -27,9 +27,7 @@ import javax.annotation.Nullable;
import net.shibboleth.idp.cas.ticket.impl.TicketIdentifierGenerationStrategy;
import net.shibboleth.idp.profile.config.AbstractConditionalProfileConfiguration;
import net.shibboleth.idp.profile.config.SecurityConfiguration;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
import net.shibboleth.utilities.java.support.component.InitializableComponent;
import net.shibboleth.utilities.java.support.logic.Constraint;
@@ -50,34 +48,26 @@ public abstract class AbstractProtocolConfiguration extends AbstractConditionalP
public static final String PROTOCOL_URI = "https://www.apereo.org/cas/protocol";
/** Lookup function to supply {@link #ticketValidityPeriod} property. */
- @Nullable private Function<ProfileRequestContext, Long> ticketValidityPeriodLookupStrategy;
+ @Nullable private Function<ProfileRequestContext,Duration> ticketValidityPeriodLookupStrategy;
/** Validity time period of tickets. */
- @Duration @Positive private long ticketValidityPeriod;
+ @Nonnull private Duration ticketValidityPeriod;
/** Whether attributes should be resolved in the course of the profile. */
@Nonnull private Predicate<ProfileRequestContext> resolveAttributesPredicate;
/**
* Creates a new configuration instance.
- *
- * @param profileId Unique profile identifier.
- */
- public AbstractProtocolConfiguration(@Nonnull @NotEmpty final String profileId) {
- this(profileId, 15000L);
- }
-
- /**
- * Creates a new configuration instance.
*
- * @param profileId Unique profile identifier.
- * @param ticketTTL Ticket validity period in milliseconds.
+ * @param profileId Unique profile identifier
*/
- public AbstractProtocolConfiguration(@Nonnull @NotEmpty final String profileId, @Positive final long ticketTTL) {
+ public AbstractProtocolConfiguration(@Nonnull @NotEmpty final String profileId) {
super(profileId);
+
resolveAttributesPredicate = Predicates.alwaysTrue();
- ticketValidityPeriod = ticketTTL;
- setSecurityConfiguration(new SecurityConfiguration(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES),
+ ticketValidityPeriod = Duration.ofSeconds(15);
+
+ setSecurityConfiguration(new SecurityConfiguration(Duration.ofMinutes(5),
new TicketIdentifierGenerationStrategy(getDefaultTicketPrefix(), getDefaultTicketLength())));
}
@@ -91,21 +81,22 @@ public abstract class AbstractProtocolConfiguration extends AbstractConditionalP
/**
* Get ticket validity period.
*
- * @return Ticket validity period in milliseconds.
+ * @return ticket validity period
*/
- @Positive @Duration public long getTicketValidityPeriod() {
- return Constraint.isGreaterThan(0,
- getIndirectProperty(ticketValidityPeriodLookupStrategy, ticketValidityPeriod),
- "Ticket validity period must be positive.");
+ @Nonnull public Duration getTicketValidityPeriod() {
+ return getIndirectProperty(ticketValidityPeriodLookupStrategy, ticketValidityPeriod);
}
/**
* Sets the ticket validity period.
*
- * @param millis Ticket validity period in milliseconds.
+ * @param ticketTTL ticket validity period
*/
- @Duration public void setTicketValidityPeriod(@Duration @Positive final long millis) {
- ticketValidityPeriod = Constraint.isGreaterThan(0, millis, "Ticket validity period must be positive.");
+ public void setTicketValidityPeriod(@Nonnull final Duration ticketTTL) {
+ Constraint.isNotNull(ticketTTL, "Ticket lifetime cannot be null");
+ Constraint.isFalse(ticketTTL.isNegative() || ticketTTL.isZero(), "Ticket lifetime must be greater than 0");
+
+ ticketValidityPeriod = ticketTTL;
}
/**
@@ -115,7 +106,8 @@ public abstract class AbstractProtocolConfiguration extends AbstractConditionalP
*
* @since 3.3.0
*/
- public void setTicketValidityPeriodLookupStrategy(@Nullable final Function<ProfileRequestContext, Long> strategy) {
+ public void setTicketValidityPeriodLookupStrategy(
+ @Nullable final Function<ProfileRequestContext,Duration> strategy) {
ticketValidityPeriodLookupStrategy = strategy;
}
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/LoginConfiguration.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/LoginConfiguration.java
index e60b5dc..d766766 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/LoginConfiguration.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/LoginConfiguration.java
@@ -94,8 +94,6 @@ public class LoginConfiguration extends AbstractProtocolConfiguration
/** Creates a new instance. */
public LoginConfiguration() {
super(PROFILE_ID);
- // Service tickets valid for 15s by default
- setTicketValidityPeriod(15000);
authenticationFlows = Collections.emptySet();
postAuthenticationFlows = Collections.emptyList();
defaultAuthenticationContexts = Collections.emptyList();
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ProxyConfiguration.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ProxyConfiguration.java
index f2d92f9..01be4c6 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ProxyConfiguration.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ProxyConfiguration.java
@@ -41,8 +41,6 @@ public class ProxyConfiguration extends AbstractProtocolConfiguration {
/** Creates a new instance. */
public ProxyConfiguration() {
super(PROFILE_ID);
- // Proxy tickets valid for 15s by default
- setTicketValidityPeriod(15000);
}
/** {@inheritDoc} */
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ValidateConfiguration.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ValidateConfiguration.java
index d345afc..73531d8 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ValidateConfiguration.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/config/impl/ValidateConfiguration.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.cas.config.impl;
+import java.time.Duration;
import java.util.Comparator;
import java.util.function.Function;
@@ -72,9 +73,11 @@ public class ValidateConfiguration extends AbstractProtocolConfiguration {
/** Creates a new instance. */
public ValidateConfiguration() {
+ super(PROFILE_ID);
+
// Ticket validity period for this configuration container applies to proxy-granting tickets
// Default to 12H
- super(PROFILE_ID, 12 * 60 * 60 * 1000);
+ setTicketValidityPeriod(Duration.ofHours(12));
pgtIOUGenerator = new TicketIdentifierGenerationStrategy("PGTIOU", 50);
serviceComparator = new DefaultServiceComparator();
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketAction.java
index eef41d3..30bd139 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantProxyTicketAction.java
@@ -151,7 +151,7 @@ public class GrantProxyTicketAction extends AbstractCASProtocolAction<ProxyTicke
log.debug("Granting proxy ticket for {}", request.getTargetService());
pt = casTicketService.createProxyTicket(
config.getSecurityConfiguration().getIdGenerator().generateIdentifier(),
- Instant.now().plusMillis(config.getTicketValidityPeriod()),
+ Instant.now().plus(config.getTicketValidityPeriod()),
pgt,
request.getTargetService());
} catch (final RuntimeException e) {
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantServiceTicketAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantServiceTicketAction.java
index 81a0d38..901a30e 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantServiceTicketAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/GrantServiceTicketAction.java
@@ -126,7 +126,7 @@ public class GrantServiceTicketAction extends AbstractCASProtocolAction<ServiceT
authnResult.getAuthenticationFlowId());
ticket = ticketServiceEx.createServiceTicket(
config.getSecurityConfiguration().getIdGenerator().generateIdentifier(),
- Instant.now().plusMillis(config.getTicketValidityPeriod()),
+ Instant.now().plus(config.getTicketValidityPeriod()),
request.getService(),
state,
request.isRenew());
diff --git a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java
index c5e7355..f45e5c0 100644
--- a/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java
+++ b/idp-cas-impl/src/main/java/net/shibboleth/idp/cas/flow/impl/ValidateProxyCallbackAction.java
@@ -124,7 +124,7 @@ public class ValidateProxyCallbackAction
try {
log.debug("Attempting proxy authentication to {}", proxyCallbackUri);
proxyValidator.validate(profileRequestContext, proxyCallbackUri);
- final Instant expiration = Instant.now().plusMillis(config.getTicketValidityPeriod());
+ final Instant expiration = Instant.now().plus(config.getTicketValidityPeriod());
if (ticket instanceof ServiceTicket) {
ticketServiceEx.createProxyGrantingTicket(proxyIds.getPgtId(), expiration, (ServiceTicket) ticket);
} else {
diff --git a/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/AbstractConsentIndexedStorageAction.java b/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/AbstractConsentIndexedStorageAction.java
index c786b51..b65c2e7 100644
--- a/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/AbstractConsentIndexedStorageAction.java
+++ b/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/AbstractConsentIndexedStorageAction.java
@@ -18,6 +18,7 @@
package net.shibboleth.idp.consent.flow.storage.impl;
import java.io.IOException;
+import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -323,16 +324,18 @@ public class AbstractConsentIndexedStorageAction extends AbstractConsentStorageA
final String context = result.getStorageContext();
final String key = result.getStorageKey();
final String value = result.getStorageValue();
- final Long expiration = result.getStorageExpiration();
+ final Instant expiration = result.getStorageExpiration();
// Create / update loop until we succeed or exhaust attempts.
int attempts = 10;
boolean success = false;
do {
- success = getStorageService().create(context, key, value, expiration);
+ success = getStorageService().create(context, key, value,
+ expiration != null ? expiration.toEpochMilli() : null);
if (!success) {
// The record already exists, so we need to overwrite via an update.
- success = getStorageService().update(context, key, value, expiration);
+ success = getStorageService().update(context, key, value,
+ expiration != null ? expiration.toEpochMilli() : null);
}
} while (!success && attempts-- > 0);
diff --git a/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/CreateGlobalConsentResult.java b/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/CreateGlobalConsentResult.java
index b794195..9cf9c95 100644
--- a/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/CreateGlobalConsentResult.java
+++ b/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/CreateGlobalConsentResult.java
@@ -58,7 +58,7 @@ public class CreateGlobalConsentResult extends AbstractConsentIndexedStorageActi
final String value =
getStorageSerializer().serialize(Collections.singletonMap(globalConsent.getId(), globalConsent));
- final long expiration = Instant.now().plus(getConsentFlowDescriptor().getLifetime()).toEpochMilli();
+ final Instant expiration = Instant.now().plus(getConsentFlowDescriptor().getLifetime());
final ProfileInterceptorResult result =
new ConsentResult(getStorageContext(), getStorageKey(), value, expiration);
diff --git a/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/CreateResult.java b/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/CreateResult.java
index de58a29..4fdcc0b 100644
--- a/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/CreateResult.java
+++ b/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/flow/storage/impl/CreateResult.java
@@ -71,7 +71,7 @@ public class CreateResult extends AbstractConsentIndexedStorageAction {
final Map<String, Consent> currentConsents = getConsentContext().getCurrentConsents();
final String value = getStorageSerializer().serialize(currentConsents);
- final long expiration = Instant.now().plus(getConsentFlowDescriptor().getLifetime()).toEpochMilli();
+ final Instant expiration = Instant.now().plus(getConsentFlowDescriptor().getLifetime());
final ProfileInterceptorResult result =
new ConsentResult(getStorageContext(), getStorageKey(), value, expiration);
diff --git a/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/storage/impl/ConsentResult.java b/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/storage/impl/ConsentResult.java
index 5a8de34..8aeceb1 100644
--- a/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/storage/impl/ConsentResult.java
+++ b/idp-consent-impl/src/main/java/net/shibboleth/idp/consent/storage/impl/ConsentResult.java
@@ -17,15 +17,15 @@
package net.shibboleth.idp.consent.storage.impl;
+import java.time.Instant;
+
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import com.google.common.base.MoreObjects;
import net.shibboleth.idp.profile.interceptor.AbstractProfileInterceptorResult;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
/**
* The result of a consent flow, suitable for storage.
@@ -44,7 +44,7 @@ public class ConsentResult extends AbstractProfileInterceptorResult {
@Nonnull @NotEmpty final String context,
@Nonnull @NotEmpty final String key,
@Nonnull @NotEmpty final String value,
- @Nullable @Positive @Duration final Long expiration) {
+ @Nullable final Instant expiration) {
super(context, key, value, expiration);
}
diff --git a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/SecurityConfiguration.java b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/SecurityConfiguration.java
index 83fcf74..ec6f9af 100644
--- a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/SecurityConfiguration.java
+++ b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/SecurityConfiguration.java
@@ -17,13 +17,11 @@
package net.shibboleth.idp.profile.config;
-import java.util.concurrent.TimeUnit;
+import java.time.Duration;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import net.shibboleth.utilities.java.support.annotation.Duration;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.security.IdentifierGenerationStrategy;
import net.shibboleth.utilities.java.support.security.SecureRandomIdentifierGenerationStrategy;
@@ -38,8 +36,8 @@ import org.opensaml.xmlsec.SignatureValidationConfiguration;
/** Configuration for security behavior of profiles. */
public class SecurityConfiguration {
- /** Acceptable clock skew expressed in milliseconds. */
- @Duration @Positive private final long clockSkew;
+ /** Acceptable clock skew. */
+ @Nonnull private final Duration clockSkew;
/** Generator used to generate various secure IDs (e.g., message identifiers). */
@Nonnull private final IdentifierGenerationStrategy idGenerator;
@@ -69,7 +67,7 @@ public class SecurityConfiguration {
* {@link SecureRandomIdentifierGenerationStrategy} using the SHA1PRNG algorithm.
*/
public SecurityConfiguration() {
- clockSkew = TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES);
+ clockSkew = Duration.ofMinutes(5);
idGenerator = new SecureRandomIdentifierGenerationStrategy();
}
@@ -79,18 +77,20 @@ public class SecurityConfiguration {
* @param skew the clock skew, must be greater than 0
* @param generator the identifier generator, must not be null
*/
- public SecurityConfiguration(@Duration @Positive final long skew,
- @Nonnull final IdentifierGenerationStrategy generator) {
- clockSkew = (int) Constraint.isGreaterThan(0, skew, "Clock skew must be greater than 0");
+ public SecurityConfiguration(@Nonnull final Duration skew, @Nonnull final IdentifierGenerationStrategy generator) {
+ Constraint.isNotNull(skew, "Clock skew cannot be null");
+ Constraint.isFalse(skew.isNegative() || skew.isZero(), "Clock skew must be greater than 0");
+
+ clockSkew = skew;
idGenerator = Constraint.isNotNull(generator, "Identifier generator cannot be null");
}
/**
- * Get the acceptable clock skew expressed in milliseconds.
+ * Get the acceptable clock skew.
*
- * @return acceptable clock skew expressed in milliseconds
+ * @return acceptable clock skew
*/
- @Positive public long getClockSkew() {
+ @Nonnull public Duration getClockSkew() {
return clockSkew;
}
diff --git a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/AbstractProfileInterceptorResult.java b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/AbstractProfileInterceptorResult.java
index add34f6..708adb8 100644
--- a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/AbstractProfileInterceptorResult.java
+++ b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/AbstractProfileInterceptorResult.java
@@ -17,12 +17,12 @@
package net.shibboleth.idp.profile.interceptor;
+import java.time.Instant;
+
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.component.AbstractIdentifiableInitializableComponent;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.primitive.StringSupport;
@@ -43,7 +43,7 @@ public abstract class AbstractProfileInterceptorResult extends AbstractIdentifia
@Nonnull @NotEmpty private String storageValue;
/** Storage expiration. */
- @Nullable @Positive @Duration private Long storageExpiration;
+ @Nullable private Instant storageExpiration;
/**
* Constructor.
@@ -57,35 +57,36 @@ public abstract class AbstractProfileInterceptorResult extends AbstractIdentifia
@Nonnull @NotEmpty final String context,
@Nonnull @NotEmpty final String key,
@Nonnull @NotEmpty final String value,
- @Nullable @Positive @Duration final Long expiration) {
+ @Nullable final Instant expiration) {
storageContext =
Constraint.isNotNull(StringSupport.trimOrNull(context), "Storage context cannot be null nor empty");
storageKey = Constraint.isNotNull(StringSupport.trimOrNull(key), "Storage key cannot be null nor empty");
storageValue = Constraint.isNotNull(StringSupport.trimOrNull(value), "Storage value cannot be null nor empty");
if (expiration != null) {
- storageExpiration = Constraint.isGreaterThan(0, expiration, "Storage expiration must be greater than 0");
+ Constraint.isGreaterThan(0, expiration.toEpochMilli(), "Storage expiration must be greater than 0");
+ storageExpiration = expiration;
}
}
/** {@inheritDoc} */
- @Override @Nonnull @NotEmpty public String getStorageContext() {
+ @Nonnull @NotEmpty public String getStorageContext() {
return storageContext;
}
/** {@inheritDoc} */
- @Override @Nonnull @NotEmpty public String getStorageKey() {
+ @Nonnull @NotEmpty public String getStorageKey() {
return storageKey;
}
/** {@inheritDoc} */
- @Override @Nonnull @NotEmpty public String getStorageValue() {
+ @Nonnull @NotEmpty public String getStorageValue() {
return storageValue;
}
/** {@inheritDoc} */
- @Override
- @Nullable @Positive @Duration public Long getStorageExpiration() {
+ @Nullable public Instant getStorageExpiration() {
return storageExpiration;
}
-}
+
+}
\ No newline at end of file
diff --git a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/ProfileInterceptorResult.java b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/ProfileInterceptorResult.java
index 1d6d904..47ee001 100644
--- a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/ProfileInterceptorResult.java
+++ b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/interceptor/ProfileInterceptorResult.java
@@ -17,11 +17,12 @@
package net.shibboleth.idp.profile.interceptor;
+import java.time.Instant;
+
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.component.IdentifiedComponent;
/**
@@ -56,5 +57,6 @@ public interface ProfileInterceptorResult extends IdentifiedComponent {
*
* @return the storage expiration
*/
- @Nullable @Positive Long getStorageExpiration();
-}
+ @Nullable Instant getStorageExpiration();
+
+}
\ No newline at end of file
diff --git a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/logic/DateAttributePredicate.java b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/logic/DateAttributePredicate.java
index 0d43a80..2d7c38f 100644
--- a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/logic/DateAttributePredicate.java
+++ b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/logic/DateAttributePredicate.java
@@ -20,7 +20,6 @@ package net.shibboleth.idp.profile.logic;
import net.shibboleth.idp.attribute.IdPAttribute;
import net.shibboleth.idp.attribute.IdPAttributeValue;
import net.shibboleth.idp.attribute.StringAttributeValue;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.ParameterName;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
@@ -150,18 +149,6 @@ public class DateAttributePredicate extends AbstractAttributePredicate {
}
/**
- * Set the system time offset in milliseconds, which affects the reference date for comparisons.
- *
- * <p>By default all comparisons are against system time, i.e. zero offset.</p>
- *
- * @param offset System time offset. A negative value decreases the target date (sooner);
- * a positive value increases the target date (later).
- */
- @Duration public void setOffset(@Duration final long offset) {
- systemTimeOffset = java.time.Duration.ofMillis(offset);
- }
-
- /**
* Set the system time offset, which affects the reference date for comparisons.
*
* <p>By default all comparisons are against system time, i.e. zero offset.</p>
diff --git a/idp-profile-api/src/test/java/net/shibboleth/idp/profile/interceptor/AbstractProfileInterceptorResultTest.java b/idp-profile-api/src/test/java/net/shibboleth/idp/profile/interceptor/AbstractProfileInterceptorResultTest.java
index f1ba005..908658d 100644
--- a/idp-profile-api/src/test/java/net/shibboleth/idp/profile/interceptor/AbstractProfileInterceptorResultTest.java
+++ b/idp-profile-api/src/test/java/net/shibboleth/idp/profile/interceptor/AbstractProfileInterceptorResultTest.java
@@ -17,12 +17,12 @@
package net.shibboleth.idp.profile.interceptor;
+import java.time.Instant;
+
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.logic.ConstraintViolationException;
import org.testng.Assert;
@@ -33,37 +33,37 @@ public class AbstractProfileInterceptorResultTest {
@Test(expectedExceptions = ConstraintViolationException.class)
public void testEmptyContext() {
- new MockAbstractProfileInterceptorResult("", "key", "value", 100L);
+ new MockAbstractProfileInterceptorResult("", "key", "value", Instant.ofEpochMilli(100));
}
@Test(expectedExceptions = ConstraintViolationException.class)
public void testEmptyKey() {
- new MockAbstractProfileInterceptorResult("context", "", "value", 100L);
+ new MockAbstractProfileInterceptorResult("context", "", "value", Instant.ofEpochMilli(100));
}
@Test(expectedExceptions = ConstraintViolationException.class)
public void testEmptyValue() {
- new MockAbstractProfileInterceptorResult("context", "key", "", 100L);
+ new MockAbstractProfileInterceptorResult("context", "key", "", Instant.ofEpochMilli(100));
}
@Test(expectedExceptions = ConstraintViolationException.class)
public void testNullContext() {
- new MockAbstractProfileInterceptorResult(null, "key", "value", 100L);
+ new MockAbstractProfileInterceptorResult(null, "key", "value", Instant.ofEpochMilli(100));
}
@Test(expectedExceptions = ConstraintViolationException.class)
public void testNullKey() {
- new MockAbstractProfileInterceptorResult("context", null, "value", 100L);
+ new MockAbstractProfileInterceptorResult("context", null, "value", Instant.ofEpochMilli(100));
}
@Test(expectedExceptions = ConstraintViolationException.class)
public void testNullValue() {
- new MockAbstractProfileInterceptorResult("context", "key", null, 100L);
+ new MockAbstractProfileInterceptorResult("context", "key", null, Instant.ofEpochMilli(100));
}
@Test(expectedExceptions = ConstraintViolationException.class)
public void testNegativeExpiration() {
- new MockAbstractProfileInterceptorResult("context", "key", null, -100L);
+ new MockAbstractProfileInterceptorResult("context", "key", null, Instant.ofEpochMilli(-100));
}
@Test public void testNullExpiration() {
@@ -76,23 +76,23 @@ public class AbstractProfileInterceptorResultTest {
}
@Test(expectedExceptions = ConstraintViolationException.class) public void testZeroExpiration() {
- new MockAbstractProfileInterceptorResult("context", "key", null, 0L);
+ new MockAbstractProfileInterceptorResult("context", "key", null, Instant.ofEpochMilli(0));
}
@Test public void testResult() {
final MockAbstractProfileInterceptorResult result =
- new MockAbstractProfileInterceptorResult("context", "key", "value", 100L);
+ new MockAbstractProfileInterceptorResult("context", "key", "value", Instant.ofEpochMilli(100));
Assert.assertEquals(result.getStorageContext(), "context");
Assert.assertEquals(result.getStorageKey(), "key");
Assert.assertEquals(result.getStorageValue(), "value");
- Assert.assertEquals(result.getStorageExpiration(), Long.valueOf(100));
+ Assert.assertEquals(result.getStorageExpiration(), Instant.ofEpochMilli(100));
}
private class MockAbstractProfileInterceptorResult extends AbstractProfileInterceptorResult {
public MockAbstractProfileInterceptorResult(@Nonnull @NotEmpty final String context,
@Nonnull @NotEmpty final String key, @Nonnull @NotEmpty final String value,
- @Nullable @Positive @Duration final Long expiration) {
+ @Nullable final Instant expiration) {
super(context, key, value, expiration);
}
}
diff --git a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/interceptor/impl/WriteProfileInterceptorResultToStorage.java b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/interceptor/impl/WriteProfileInterceptorResultToStorage.java
index 75b6bfb..c8907d9 100644
--- a/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/interceptor/impl/WriteProfileInterceptorResultToStorage.java
+++ b/idp-profile-impl/src/main/java/net/shibboleth/idp/profile/interceptor/impl/WriteProfileInterceptorResultToStorage.java
@@ -18,6 +18,7 @@
package net.shibboleth.idp.profile.interceptor.impl;
import java.io.IOException;
+import java.time.Instant;
import java.util.List;
import javax.annotation.Nonnull;
@@ -108,16 +109,17 @@ public class WriteProfileInterceptorResultToStorage extends AbstractProfileInter
final String context = result.getStorageContext();
final String key = result.getStorageKey();
final String value = result.getStorageValue();
- final Long expiration = result.getStorageExpiration();
+ final Instant expiration = result.getStorageExpiration();
// Create / update loop until we succeed or exhaust attempts.
int attempts = 10;
boolean success = false;
do {
- success = storageService.create(context, key, value, expiration);
+ success = storageService.create(context, key, value, expiration != null ? expiration.toEpochMilli() : null);
if (!success) {
// The record already exists, so we need to overwrite via an update.
- success = storageService.update(context, key, value, expiration);
+ success = storageService.update(context, key, value,
+ expiration != null ? expiration.toEpochMilli() : null);
}
} while (!success && attempts-- > 0);
diff --git a/idp-profile-impl/src/test/java/net/shibboleth/idp/profile/interceptor/impl/WriteProfileInterceptorResultToStorageTest.java b/idp-profile-impl/src/test/java/net/shibboleth/idp/profile/interceptor/impl/WriteProfileInterceptorResultToStorageTest.java
index b5281ef..cc92b0f 100644
--- a/idp-profile-impl/src/test/java/net/shibboleth/idp/profile/interceptor/impl/WriteProfileInterceptorResultToStorageTest.java
+++ b/idp-profile-impl/src/test/java/net/shibboleth/idp/profile/interceptor/impl/WriteProfileInterceptorResultToStorageTest.java
@@ -28,9 +28,7 @@ import net.shibboleth.idp.profile.context.ProfileInterceptorContext;
import net.shibboleth.idp.profile.context.navigate.WebflowRequestContextProfileRequestContextLookup;
import net.shibboleth.idp.profile.interceptor.AbstractProfileInterceptorResult;
import net.shibboleth.idp.profile.interceptor.ProfileInterceptorFlowDescriptor;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import org.opensaml.profile.context.ProfileRequestContext;
import org.opensaml.storage.StorageRecord;
@@ -110,7 +108,7 @@ public class WriteProfileInterceptorResultToStorageTest {
}
@Test public void testCreateStorageRecordWithExpiration() throws Exception {
- final Long expiration = Instant.now().plusSeconds(60).toEpochMilli();
+ final Instant expiration = Instant.now().plusSeconds(60);
final MockProfileInterceptorResult result =
new MockProfileInterceptorResult("context", "key", "value", expiration);
prc.getSubcontext(ProfileInterceptorContext.class).getResults().add(result);
@@ -122,11 +120,11 @@ public class WriteProfileInterceptorResultToStorageTest {
final StorageRecord storageRecord = ss.read("context", "key");
Assert.assertNotNull(storageRecord);
Assert.assertEquals(storageRecord.getValue(), "value");
- Assert.assertEquals(storageRecord.getExpiration(), expiration);
+ Assert.assertEquals(storageRecord.getExpiration(), Long.valueOf(expiration.toEpochMilli()));
}
@Test public void testUpdateStorageRecord() throws Exception {
- final Long expiration = Instant.now().plusSeconds(60).toEpochMilli();
+ final Instant expiration = Instant.now().plusSeconds(60);
MockProfileInterceptorResult result = new MockProfileInterceptorResult("context", "key", "value", null);
prc.getSubcontext(ProfileInterceptorContext.class).getResults().add(result);
@@ -150,14 +148,14 @@ public class WriteProfileInterceptorResultToStorageTest {
storageRecord = ss.read("context", "key");
Assert.assertNotNull(storageRecord);
Assert.assertEquals(storageRecord.getValue(), "value2");
- Assert.assertEquals(storageRecord.getExpiration(), expiration);
+ Assert.assertEquals(storageRecord.getExpiration(), Long.valueOf(expiration.toEpochMilli()));
}
private class MockProfileInterceptorResult extends AbstractProfileInterceptorResult {
public MockProfileInterceptorResult(@Nonnull @NotEmpty final String context,
@Nonnull @NotEmpty final String key, @Nonnull @NotEmpty final String value,
- @Nullable @Positive @Duration final Long expiration) {
+ @Nullable final Instant expiration) {
super(context, key, value, expiration);
}
}
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/AbstractSAMLProfileConfiguration.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/AbstractSAMLProfileConfiguration.java
index e535437..1ddc275 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/AbstractSAMLProfileConfiguration.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/AbstractSAMLProfileConfiguration.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.saml.profile.config;
+import java.time.Duration;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
@@ -29,11 +30,9 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.shibboleth.idp.profile.config.AbstractConditionalProfileConfiguration;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
import net.shibboleth.utilities.java.support.logic.Constraint;
import net.shibboleth.utilities.java.support.primitive.StringSupport;
@@ -65,10 +64,10 @@ public abstract class AbstractSAMLProfileConfiguration extends AbstractCondition
@Nullable private Predicate<ProfileRequestContext> includeNotBeforePredicate;
/** Lookup function to supply {@link #assertionLifetime} property. */
- @Nullable private Function<ProfileRequestContext,Long> assertionLifetimeLookupStrategy;
+ @Nullable private Function<ProfileRequestContext,Duration> assertionLifetimeLookupStrategy;
- /** Lifetime of an assertion in milliseconds. Default value: 5 minutes */
- @Positive @Duration private long assertionLifetime;
+ /** Lifetime of an assertion. Default value: 5 minutes */
+ @Nonnull private Duration assertionLifetime;
/** Lookup function to supply {@link #assertionAudiences} property. */
@Nullable private Function<ProfileRequestContext,Collection<String>> assertionAudiencesLookupStrategy;
@@ -88,7 +87,7 @@ public abstract class AbstractSAMLProfileConfiguration extends AbstractCondition
signResponsesPredicate = Predicates.alwaysFalse();
signAssertionsPredicate = Predicates.alwaysFalse();
includeNotBeforePredicate = Predicates.alwaysTrue();
- assertionLifetime = 5 * 60 * 1000;
+ assertionLifetime = Duration.ofMinutes(5);
assertionAudiences = Collections.emptySet();
}
@@ -104,7 +103,7 @@ public abstract class AbstractSAMLProfileConfiguration extends AbstractCondition
}
/** {@inheritDoc} */
- @Override @Nonnull public Predicate<ProfileRequestContext> getSignAssertions() {
+ @Nonnull public Predicate<ProfileRequestContext> getSignAssertions() {
return signAssertionsPredicate;
}
@@ -119,7 +118,7 @@ public abstract class AbstractSAMLProfileConfiguration extends AbstractCondition
}
/** {@inheritDoc} */
- @Override @Nonnull public Predicate<ProfileRequestContext> getSignRequests() {
+ @Nonnull public Predicate<ProfileRequestContext> getSignRequests() {
return signRequestsPredicate;
}
@@ -135,7 +134,7 @@ public abstract class AbstractSAMLProfileConfiguration extends AbstractCondition
}
/** {@inheritDoc} */
- @Override @Nonnull public Predicate<ProfileRequestContext> getSignResponses() {
+ @Nonnull public Predicate<ProfileRequestContext> getSignResponses() {
return signResponsesPredicate;
}
@@ -150,18 +149,20 @@ public abstract class AbstractSAMLProfileConfiguration extends AbstractCondition
}
/** {@inheritDoc} */
- @Override @Positive @Duration public long getAssertionLifetime() {
- return Constraint.isGreaterThan(0, getIndirectProperty(assertionLifetimeLookupStrategy, assertionLifetime),
- "Assertion lifetime must be greater than 0");
+ @Nonnull public Duration getAssertionLifetime() {
+ return getIndirectProperty(assertionLifetimeLookupStrategy, assertionLifetime);
}
/**
* Set the lifetime of an assertion.
*
- * @param lifetime lifetime of an assertion in milliseconds
+ * @param lifetime lifetime of an assertion
*/
- @Duration public void setAssertionLifetime(@Positive @Duration final long lifetime) {
- assertionLifetime = Constraint.isGreaterThan(0, lifetime, "Assertion lifetime must be greater than 0");
+ public void setAssertionLifetime(@Nonnull final Duration lifetime) {
+ Constraint.isNotNull(lifetime, "Assertion lifetime cannot be null");
+ Constraint.isFalse(lifetime.isNegative() || lifetime.isZero(), "Assertion lifetime must be greater than 0");
+
+ assertionLifetime = lifetime;
}
/**
@@ -171,12 +172,12 @@ public abstract class AbstractSAMLProfileConfiguration extends AbstractCondition
*
* @since 3.3.0
*/
- public void setAssertionLifetimeLookupStrategy(@Nullable final Function<ProfileRequestContext,Long> strategy) {
+ public void setAssertionLifetimeLookupStrategy(@Nullable final Function<ProfileRequestContext,Duration> strategy) {
assertionLifetimeLookupStrategy = strategy;
}
/**{@inheritDoc} */
- @Override public boolean includeConditionsNotBefore() {
+ public boolean includeConditionsNotBefore() {
return includeNotBeforePredicate.test(getProfileRequestContext());
}
@@ -215,7 +216,7 @@ public abstract class AbstractSAMLProfileConfiguration extends AbstractCondition
}
/** {@inheritDoc} */
- @Override @Nonnull @NonnullElements @NotLive public Set<String> getAdditionalAudiencesForAssertion() {
+ @Nonnull @NonnullElements @NotLive public Set<String> getAdditionalAudiencesForAssertion() {
return ImmutableSet.copyOf(getIndirectProperty(assertionAudiencesLookupStrategy, assertionAudiences));
}
@@ -224,22 +225,6 @@ public abstract class AbstractSAMLProfileConfiguration extends AbstractCondition
* which an assertion may be shared.
*
* @param audiences the additional audiences
- *
- * @deprecated
- */
- @Deprecated
- public void setAdditionalAudienceForAssertion(@Nonnull @NonnullElements final Collection<String> audiences) {
- LoggerFactory.getLogger(AbstractSAMLProfileConfiguration.class).warn(
- "Use of deprecated property name 'additionalAudienceForAssertion', please correct to "
- + "'additionalAudiencesForAssertion'");
- setAdditionalAudiencesForAssertion(audiences);
- }
-
- /**
- * Set the set of audiences, in addition to the relying party(ies) to which the IdP is issuing the assertion, with
- * which an assertion may be shared.
- *
- * @param audiences the additional audiences
*/
public void setAdditionalAudiencesForAssertion(@Nullable @NonnullElements final Collection<String> audiences) {
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/DurationConfigurationLookupStrategy.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/DurationConfigurationLookupStrategy.java
index a8f2f08..920d581 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/DurationConfigurationLookupStrategy.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/DurationConfigurationLookupStrategy.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.saml.profile.config;
+import java.time.Duration;
import java.util.List;
import javax.annotation.Nonnull;
@@ -29,8 +30,9 @@ import org.opensaml.core.xml.schema.XSString;
import org.opensaml.saml.saml2.core.Attribute;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.core.convert.converter.Converter;
-import net.shibboleth.ext.spring.config.DurationToLongConverter;
+import net.shibboleth.ext.spring.config.StringToDurationConverter;
/**
* A strategy function that examines SAML metadata associated with a relying party and derives Long-valued
@@ -38,22 +40,22 @@ import net.shibboleth.ext.spring.config.DurationToLongConverter;
*
* @since 3.4.0
*/
-public class DurationConfigurationLookupStrategy extends AbstractMetadataDrivenConfigurationLookupStrategy<Long> {
+public class DurationConfigurationLookupStrategy extends AbstractMetadataDrivenConfigurationLookupStrategy<Duration> {
/** Class logger. */
@Nonnull private final Logger log = LoggerFactory.getLogger(DurationConfigurationLookupStrategy.class);
/** Converter to handle duration strings. */
- @Nonnull private final DurationToLongConverter durationConverter;
+ @Nonnull private final Converter<String,Duration> durationConverter;
/** Constructor. */
public DurationConfigurationLookupStrategy() {
- durationConverter = new DurationToLongConverter();
+ durationConverter = new StringToDurationConverter();
}
/** {@inheritDoc} */
@Override
- @Nullable protected Long doTranslate(@Nonnull final Attribute tag) {
+ @Nullable protected Duration doTranslate(@Nonnull final Attribute tag) {
final List<XMLObject> values = tag.getAttributeValues();
if (values.size() != 1) {
@@ -61,7 +63,7 @@ public class DurationConfigurationLookupStrategy extends AbstractMetadataDrivenC
return null;
}
- log.debug("Converting tag '{}' to Long duration property", tag.getName());
+ log.debug("Converting tag '{}' to Duration property", tag.getName());
return xmlObjectToDuration(values.get(0));
}
@@ -73,7 +75,7 @@ public class DurationConfigurationLookupStrategy extends AbstractMetadataDrivenC
*
* @return the converted value, or null
*/
- @Nullable private Long xmlObjectToDuration(@Nonnull final XMLObject object) {
+ @Nullable private Duration xmlObjectToDuration(@Nonnull final XMLObject object) {
if (object instanceof XSString) {
final String value = ((XSString) object).getValue();
if (value != null) {
@@ -88,7 +90,7 @@ public class DurationConfigurationLookupStrategy extends AbstractMetadataDrivenC
}
} else if (object instanceof XSInteger) {
final Integer value = ((XSInteger) object).getValue();
- return value != null ? value.longValue() : null;
+ return value != null ? Duration.ofMillis(value.longValue()) : null;
} else if (object instanceof XSAny) {
final XSAny wc = (XSAny) object;
if (wc.getUnknownAttributes().isEmpty() && wc.getUnknownXMLObjects().isEmpty()) {
@@ -106,7 +108,7 @@ public class DurationConfigurationLookupStrategy extends AbstractMetadataDrivenC
}
}
- log.error("Unsupported conversion to Long duration from XMLObject type ({})", object.getClass().getName());
+ log.error("Unsupported conversion to Duration from XMLObject type ({})", object.getClass().getName());
return null;
}
// Checkstyle: CyclomaticComplexity ON
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/SAMLProfileConfiguration.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/SAMLProfileConfiguration.java
index 42f913d..e5b4a35 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/SAMLProfileConfiguration.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/SAMLProfileConfiguration.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.saml.profile.config;
+import java.time.Duration;
import java.util.Set;
import java.util.function.Predicate;
@@ -27,7 +28,6 @@ import org.opensaml.profile.context.ProfileRequestContext;
import net.shibboleth.idp.profile.config.ProfileConfiguration;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotLive;
-import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
import net.shibboleth.utilities.java.support.annotation.constraint.Unmodifiable;
/** Common interface for SAML profile configurations. */
@@ -55,11 +55,11 @@ public interface SAMLProfileConfiguration extends ProfileConfiguration {
@Nonnull Predicate<ProfileRequestContext> getSignResponses();
/**
- * Get the lifetime of generated assertions in milliseconds.
+ * Get the lifetime of generated assertions.
*
- * @return lifetime of generated assertions in milliseconds
+ * @return lifetime of generated assertions
*/
- @Positive long getAssertionLifetime();
+ @Nonnull Duration getAssertionLifetime();
/**
* Get an unmodifiable set of audiences, in addition to the relying party(ies) to which the IdP is issuing the
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/AssertionLifetimeLookupFunction.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/AssertionLifetimeLookupFunction.java
index ce6d5b6..a252936 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/AssertionLifetimeLookupFunction.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/AssertionLifetimeLookupFunction.java
@@ -43,7 +43,7 @@ public class AssertionLifetimeLookupFunction extends AbstractRelyingPartyLookupF
if (rpc != null) {
final ProfileConfiguration pc = rpc.getProfileConfig();
if (pc != null && pc instanceof SAMLProfileConfiguration) {
- return Duration.ofMillis(((SAMLProfileConfiguration) pc).getAssertionLifetime());
+ return ((SAMLProfileConfiguration) pc).getAssertionLifetime();
}
}
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/SessionLifetimeLookupFunction.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/SessionLifetimeLookupFunction.java
index 50813fb..37d1a02 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/SessionLifetimeLookupFunction.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/profile/config/navigate/SessionLifetimeLookupFunction.java
@@ -17,6 +17,8 @@
package net.shibboleth.idp.saml.profile.config.navigate;
+import java.time.Duration;
+
import javax.annotation.Nullable;
import net.shibboleth.idp.profile.config.ProfileConfiguration;
@@ -33,10 +35,10 @@ import org.opensaml.profile.context.ProfileRequestContext;
*
* <p>If a specific setting is unavailable, zero is returned.</p>
*/
-public class SessionLifetimeLookupFunction extends AbstractRelyingPartyLookupFunction<Long> {
+public class SessionLifetimeLookupFunction extends AbstractRelyingPartyLookupFunction<Duration> {
/** {@inheritDoc} */
- @Nullable public Long 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();
diff --git a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java
index 734938c..505f91c 100644
--- a/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java
+++ b/idp-saml-api/src/main/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfiguration.java
@@ -18,6 +18,7 @@
package net.shibboleth.idp.saml.saml2.profile.config;
import java.security.Principal;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -32,7 +33,6 @@ import javax.annotation.Nullable;
import net.shibboleth.idp.authn.config.AuthenticationProfileConfiguration;
import net.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NonNegative;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
@@ -53,7 +53,7 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2ArtifactAwarePr
implements AuthenticationProfileConfiguration {
/** ID for this profile configuration. */
- public static final String PROFILE_ID = "http://shibboleth.net/ns/profiles/saml2/sso/browser";
+ @Nonnull @NotEmpty public static final String PROFILE_ID = "http://shibboleth.net/ns/profiles/saml2/sso/browser";
/** Bit constant for RequestedAuthnContext feature. */
public static final int FEATURE_AUTHNCONTEXT = 0x1;
@@ -71,13 +71,10 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2ArtifactAwarePr
@Nonnull private Predicate<ProfileRequestContext> skipEndpointValidationWhenSignedPredicate;
/** Lookup function to supply {@link #maximumSPSessionLifetime} property. */
- @Nullable private Function<ProfileRequestContext,Long> maximumSPSessionLifetimeLookupStrategy;
+ @Nullable private Function<ProfileRequestContext,Duration> maximumSPSessionLifetimeLookupStrategy;
- /**
- * The maximum amount of time, in milliseconds, the service provider should maintain a session for the user. A value
- * of 0 (the default) indicates no cap is put on the SP's session lifetime.
- */
- @Duration @NonNegative private long maximumSPSessionLifetime;
+ /** The maximum amount of time the service provider should maintain a session for the user. */
+ @Nullable private Duration maximumSPSessionLifetime;
/**
* The predicate used to determine if produced assertions may be delegated.
@@ -133,7 +130,6 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2ArtifactAwarePr
includeAttributeStatementPredicate = Predicates.alwaysTrue();
forceAuthnPredicate = Predicates.alwaysFalse();
skipEndpointValidationWhenSignedPredicate = Predicates.alwaysFalse();
- maximumSPSessionLifetime = 0;
maximumTokenDelegationChainLength = 1;
allowDelegationPredicate = Predicates.<ProfileRequestContext>alwaysFalse();
defaultAuthenticationContexts = Collections.emptyList();
@@ -143,20 +139,6 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2ArtifactAwarePr
}
/**
- * Get whether attributes should be resolved during the profile.
- *
- * <p>Default is true</p>
- *
- * @return true iff attributes should be resolved
- *
- * @deprecated Use {@link #getResolveAttributesPredicate()} instead.
- */
- @Deprecated
- public boolean resolveAttributes() {
- return resolveAttributesPredicate.test(getProfileRequestContext());
- }
-
- /**
* Set whether attributes should be resolved during the profile.
*
* @param flag flag to set
@@ -189,20 +171,6 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2ArtifactAwarePr
}
/**
- * Get whether responses to the authentication request should include an attribute statement.
- *
- * <p>Default is true</p>
- *
- * @return whether responses to the authentication request should include an attribute statement
- *
- * @deprecated Use {@link #getIncludeAttributeStatementPredicate()} instead.
- */
- @Deprecated
- public boolean includeAttributeStatement() {
- return includeAttributeStatementPredicate.test(getProfileRequestContext());
- }
-
- /**
* Set whether responses to the authentication request should include an attribute statement.
*
* @param include flag to set
@@ -272,18 +240,6 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2ArtifactAwarePr
}
/**
- * Get whether the response endpoint should be validated if the request is signed.
- *
- * @return whether the response endpoint should be validated if the request is signed
- *
- * @deprecated Use {@link #getSkipEndpointValidationWhenSignedPredicate()} instead.
- */
- @Deprecated
- public boolean skipEndpointValidationWhenSigned() {
- return skipEndpointValidationWhenSignedPredicate.test(getProfileRequestContext());
- }
-
- /**
* Set whether the response endpoint should be validated if the request is signed.
*
* @param skip whether the response endpoint should be validated if the request is signed
@@ -318,27 +274,26 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2ArtifactAwarePr
}
/**
- * Get the maximum amount of time, in milliseconds, the service provider should maintain a session for the user
- * based on the authentication assertion. A value of 0 is interpreted as an unlimited lifetime.
+ * Get the maximum amount of time the service provider should maintain a session for the user
+ * based on the authentication assertion. A null or 0 is interpreted as an unlimited lifetime.
*
* @return max lifetime of service provider should maintain a session
*/
- @NonNegative @Duration public long getMaximumSPSessionLifetime() {
- return Constraint.isGreaterThanOrEqual(0,
- getIndirectProperty(maximumSPSessionLifetimeLookupStrategy, maximumSPSessionLifetime),
- "Maximum SP session lifetime must be greater or equal to 0");
+ @Nullable public Duration getMaximumSPSessionLifetime() {
+ return getIndirectProperty(maximumSPSessionLifetimeLookupStrategy, maximumSPSessionLifetime);
}
/**
- * Set the maximum amount of time, in milliseconds, the service provider should maintain a session for the user
- * based on the authentication assertion. A value of 0 is interpreted as an unlimited lifetime.
+ * Set the maximum amount of time the service provider should maintain a session for the user
+ * based on the authentication assertion. A null or 0 is interpreted as an unlimited lifetime.
*
* @param lifetime max lifetime of service provider should maintain a session
*/
- @Duration public void setMaximumSPSessionLifetime(@Duration @NonNegative final long lifetime) {
- maximumSPSessionLifetime =
- Constraint.isGreaterThanOrEqual(0, lifetime,
- "Maximum SP session lifetime must be greater than or equal to 0");
+ public void setMaximumSPSessionLifetime(@Nullable final Duration lifetime) {
+ Constraint.isFalse(lifetime != null && lifetime.isNegative(),
+ "Maximum SP session lifetime must be greater than or equal to 0");
+
+ maximumSPSessionLifetime = lifetime;
}
/**
@@ -349,53 +304,15 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2ArtifactAwarePr
* @since 3.3.0
*/
public void setMaximumSPSessionLifetimeLookupStrategy(
- @Nullable final Function<ProfileRequestContext,Long> strategy) {
+ @Nullable final Function<ProfileRequestContext,Duration> strategy) {
maximumSPSessionLifetimeLookupStrategy = strategy;
}
-
- /**
- * Get whether produced assertions may be delegated.
- *
- * @return whether produced assertions may be delegated, as a {@link Boolean}. May be null.
- *
- * @deprecated use instead {@link #getAllowDelegation()} predicate
- */
- @Deprecated
- public Boolean getAllowingDelegation() {
- return allowDelegationPredicate.test(getProfileRequestContext());
- }
-
- /**
- * Set whether produced assertions may be delegated.
- *
- * @param isAllowed whether produced assertions may be delegated
- */
- @Deprecated
- public void setAllowingDelegation(final Boolean isAllowed) {
- if (isAllowed != null) {
- allowDelegationPredicate = isAllowed ? Predicates.<ProfileRequestContext>alwaysTrue()
- : Predicates.<ProfileRequestContext>alwaysFalse();
- } else {
- allowDelegationPredicate = Predicates.alwaysFalse();
- }
- }
-
- /**
- * Get whether produced assertions may be delegated.
- *
- * @return whether produced assertions may be delegated
- */
- public boolean isAllowingDelegation() {
- return allowDelegationPredicate.test(getProfileRequestContext());
- }
-
/**
* Get the predicate used to determine if produced assertions may be delegated.
*
* @return predicate used to determine if produced assertions may be delegated
*/
-
@Nonnull public Predicate<ProfileRequestContext> getAllowDelegation() {
return allowDelegationPredicate;
}
@@ -405,7 +322,6 @@ public class BrowserSSOProfileConfiguration extends AbstractSAML2ArtifactAwarePr
*
* @param predicate used to determine if produced assertions may be delegated
*/
-
public void setAllowDelegation(@Nonnull final Predicate<ProfileRequestContext> predicate) {
allowDelegationPredicate = Constraint.isNotNull(predicate, "Allow delegation predicate cannot be null");
}
diff --git a/idp-saml-api/src/test/java/net/shibboleth/idp/saml/profile/config/AbstractSAMLProfileConfigurationTest.java b/idp-saml-api/src/test/java/net/shibboleth/idp/saml/profile/config/AbstractSAMLProfileConfigurationTest.java
index 3f67cb9..7b783a0 100644
--- a/idp-saml-api/src/test/java/net/shibboleth/idp/saml/profile/config/AbstractSAMLProfileConfigurationTest.java
+++ b/idp-saml-api/src/test/java/net/shibboleth/idp/saml/profile/config/AbstractSAMLProfileConfigurationTest.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.saml.profile.config;
+import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
@@ -81,20 +82,20 @@ public class AbstractSAMLProfileConfigurationTest {
@Test public void testAssertionLifetime() {
final MockSAMLProfileConfiguration config = new MockSAMLProfileConfiguration();
- Assert.assertTrue(config.getAssertionLifetime() > 0);
+ Assert.assertTrue(config.getAssertionLifetime().toMillis() > 0);
- config.setAssertionLifetime(100);
- Assert.assertEquals(config.getAssertionLifetime(), 100);
+ config.setAssertionLifetime(Duration.ofMillis(100));
+ Assert.assertEquals(config.getAssertionLifetime(), Duration.ofMillis(100));
try {
- config.setAssertionLifetime(0);
+ config.setAssertionLifetime(Duration.ZERO);
Assert.fail();
} catch (ConstraintViolationException e) {
// expected this
}
try {
- config.setAssertionLifetime(-100);
+ config.setAssertionLifetime(Duration.ofMillis(-100));
Assert.fail();
} catch (ConstraintViolationException e) {
// expected this
@@ -103,11 +104,12 @@ public class AbstractSAMLProfileConfigurationTest {
@Test public void testIndirectAssertionLifetime() {
final MockSAMLProfileConfiguration config = new MockSAMLProfileConfiguration();
- config.setAssertionLifetimeLookupStrategy(FunctionSupport.<ProfileRequestContext,Long>constant(500L));
- Assert.assertEquals(config.getAssertionLifetime(), 500L);
+ config.setAssertionLifetimeLookupStrategy(
+ FunctionSupport.<ProfileRequestContext,Duration>constant(Duration.ofMillis(500)));
+ Assert.assertEquals(config.getAssertionLifetime(), Duration.ofMillis(500));
- config.setAssertionLifetimeLookupStrategy(FunctionSupport.<ProfileRequestContext,Long>constant(null));
- Assert.assertEquals(config.getAssertionLifetime(), 5 * 60 * 1000);
+ config.setAssertionLifetimeLookupStrategy(FunctionSupport.<ProfileRequestContext,Duration>constant(null));
+ Assert.assertEquals(config.getAssertionLifetime(), Duration.ofMinutes(5));
}
@Test public void testIncludeNotBefore() {
@@ -125,13 +127,12 @@ public class AbstractSAMLProfileConfigurationTest {
Assert.assertFalse(config.includeConditionsNotBefore());
}
- @SuppressWarnings("deprecation")
@Test public void testAdditionalAudiencesForAssertion() {
final MockSAMLProfileConfiguration config = new MockSAMLProfileConfiguration();
Assert.assertNotNull(config.getAdditionalAudiencesForAssertion());
Assert.assertTrue(config.getAdditionalAudiencesForAssertion().isEmpty());
- config.setAdditionalAudienceForAssertion(Arrays.asList("", null, " foo"));
+ config.setAdditionalAudiencesForAssertion(Arrays.asList("", null, " foo"));
final Set<String> audiences = config.getAdditionalAudiencesForAssertion();
Assert.assertNotNull(audiences);
@@ -145,7 +146,7 @@ public class AbstractSAMLProfileConfigurationTest {
// expected this
}
- config.setAdditionalAudienceForAssertion(Collections.<String>emptyList());
+ config.setAdditionalAudiencesForAssertion(Collections.<String>emptyList());
Assert.assertNotNull(config.getAdditionalAudiencesForAssertion());
Assert.assertTrue(config.getAdditionalAudiencesForAssertion().isEmpty());
}
diff --git a/idp-saml-api/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfigurationTest.java b/idp-saml-api/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfigurationTest.java
index 58146a3..89428da 100644
--- a/idp-saml-api/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfigurationTest.java
+++ b/idp-saml-api/src/test/java/net/shibboleth/idp/saml/saml2/profile/config/BrowserSSOProfileConfigurationTest.java
@@ -23,6 +23,7 @@ import net.shibboleth.idp.saml.profile.config.SAMLArtifactConfiguration;
import net.shibboleth.utilities.java.support.logic.ConstraintViolationException;
import net.shibboleth.utilities.java.support.logic.FunctionSupport;
+import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -48,97 +49,72 @@ public class BrowserSSOProfileConfigurationTest {
Assert.assertEquals(config.getId(), BrowserSSOProfileConfiguration.PROFILE_ID);
}
- @SuppressWarnings("deprecation")
@Test
public void testResolveAttributes(){
final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
- Assert.assertTrue(config.resolveAttributes());
+ Assert.assertTrue(config.getResolveAttributesPredicate().test(null));
config.setResolveAttributes(false);
- Assert.assertFalse(config.resolveAttributes());
+ Assert.assertFalse(config.getResolveAttributesPredicate().test(null));
}
- @SuppressWarnings("deprecation")
@Test
public void testIndirectResolveAttributes(){
final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
- config.setResolveAttributesPredicate(Predicates.<ProfileRequestContext>alwaysFalse());
- Assert.assertFalse(config.resolveAttributes());
+ config.setResolveAttributesPredicate(Predicates.alwaysFalse());
+ Assert.assertFalse(config.getResolveAttributesPredicate().test(null));
}
- @SuppressWarnings("deprecation")
@Test
public void testIncludeAttributeStatement(){
final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
- Assert.assertTrue(config.includeAttributeStatement());
+ Assert.assertTrue(config.getIncludeAttributeStatementPredicate().test(null));
config.setIncludeAttributeStatement(false);
- Assert.assertFalse(config.includeAttributeStatement());
+ Assert.assertFalse(config.getIncludeAttributeStatementPredicate().test(null));
}
- @SuppressWarnings("deprecation")
@Test
public void testIndirectIncludeAttributeStatement(){
final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
- config.setIncludeAttributeStatementPredicate(Predicates.<ProfileRequestContext>alwaysFalse());
- Assert.assertFalse(config.includeAttributeStatement());
+ config.setIncludeAttributeStatementPredicate(Predicates.alwaysFalse());
+ Assert.assertFalse(config.getIncludeAttributeStatementPredicate().test(null));
}
- @SuppressWarnings("deprecation")
@Test
public void testSkipEndpointValidationWhenSigned() {
BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
- Assert.assertFalse(config.skipEndpointValidationWhenSigned());
+ Assert.assertFalse(config.getSkipEndpointValidationWhenSignedPredicate().test(null));
config.setSkipEndpointValidationWhenSigned(true);
- Assert.assertTrue(config.skipEndpointValidationWhenSigned());
+ Assert.assertTrue(config.getSkipEndpointValidationWhenSignedPredicate().test(null));
}
- @SuppressWarnings("deprecation")
@Test
public void testIndirectEndpointValidationWhenSigned(){
final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
- config.setSkipEndpointValidationWhenSignedPredicate(Predicates.<ProfileRequestContext>alwaysTrue());
- Assert.assertTrue(config.skipEndpointValidationWhenSigned());
+ config.setSkipEndpointValidationWhenSignedPredicate(Predicates.alwaysTrue());
+ Assert.assertTrue(config.getSkipEndpointValidationWhenSignedPredicate().test(null));
}
@Test
public void testMaximumSPSessionLifeTime() {
final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
- Assert.assertEquals(config.getMaximumSPSessionLifetime(), 0);
+ Assert.assertNull(config.getMaximumSPSessionLifetime());
- config.setMaximumSPSessionLifetime(1000);
- Assert.assertEquals(config.getMaximumSPSessionLifetime(), 1000);
+ config.setMaximumSPSessionLifetime(Duration.ofSeconds(1));
+ Assert.assertEquals(config.getMaximumSPSessionLifetime(), Duration.ofSeconds(1));
}
@Test
public void testIndirectMaximumSPSessionLifeTime() {
final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
- config.setMaximumSPSessionLifetimeLookupStrategy(FunctionSupport.<ProfileRequestContext,Long>constant(1000L));
- Assert.assertEquals(config.getMaximumSPSessionLifetime(), 1000);
- }
-
- @SuppressWarnings("deprecation")
- @Test
- public void testAllowingDelegation() {
- // Note: testing the deprecated boolean value variant
- final BrowserSSOProfileConfiguration config = new BrowserSSOProfileConfiguration();
- Assert.assertFalse(config.isAllowingDelegation());
- Assert.assertFalse(config.getAllowingDelegation());
-
- config.setAllowingDelegation(false);
- Assert.assertFalse(config.isAllowingDelegation());
- Assert.assertFalse(config.getAllowingDelegation());
- Assert.assertEquals(config.getAllowingDelegation(), Boolean.FALSE);
-
- config.setAllowingDelegation(true);
- Assert.assertTrue(config.isAllowingDelegation());
- Assert.assertTrue(config.getAllowingDelegation());
- Assert.assertEquals(config.getAllowingDelegation(), Boolean.TRUE);
+ config.setMaximumSPSessionLifetimeLookupStrategy(FunctionSupport.constant(Duration.ofSeconds(1)));
+ Assert.assertEquals(config.getMaximumSPSessionLifetime(), Duration.ofSeconds(1));
}
@Test
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/StoredTransientIdGenerationStrategy.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/StoredTransientIdGenerationStrategy.java
index 2e5b8ef..612b7af 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/StoredTransientIdGenerationStrategy.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/nameid/impl/StoredTransientIdGenerationStrategy.java
@@ -18,10 +18,11 @@
package net.shibboleth.idp.saml.nameid.impl;
import java.io.IOException;
+import java.time.Duration;
+import java.time.Instant;
import javax.annotation.Nonnull;
-import net.shibboleth.utilities.java.support.annotation.Duration;
import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
import net.shibboleth.utilities.java.support.annotation.constraint.NotEmpty;
import net.shibboleth.utilities.java.support.annotation.constraint.Positive;
@@ -58,13 +59,13 @@ public class StoredTransientIdGenerationStrategy extends AbstractIdentifiableIni
/** Size, in bytes, of the identifier. */
private int idSize;
- /** Length, in milliseconds, identifiers are valid. */
- @Duration @Positive private long idLifetime;
+ /** Length identifiers are valid. */
+ @Nonnull private Duration idLifetime;
/** Constructor. */
public StoredTransientIdGenerationStrategy() {
idSize = 16;
- idLifetime = 1000 * 60 * 60 * 4;
+ idLifetime = Duration.ofHours(4);
}
/**
@@ -110,23 +111,26 @@ public class StoredTransientIdGenerationStrategy extends AbstractIdentifiableIni
}
/**
- * Get the time, in milliseconds, ids are valid.
+ * Get the time ids are valid.
*
- * @return time, in milliseconds, ids are valid
+ * @return time ids are valid
*/
- @Positive public long getIdLifetime() {
+ @Nonnull public Duration getIdLifetime() {
return idLifetime;
}
/**
- * Set the time, in milliseconds, ids are valid.
+ * Set the time ids are valid.
*
- * @param lifetime time, in milliseconds, ids are valid
+ * @param lifetime time ids are valid
*/
- public void setIdLifetime(@Duration @Positive final long lifetime) {
+ public void setIdLifetime(@Nonnull final Duration lifetime) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
- idLifetime = Constraint.isGreaterThan(0, lifetime, "ID lifetime must be positive");
+ Constraint.isNotNull(lifetime, "ID lifetime cannot be null");
+ Constraint.isFalse(lifetime.isNegative() || lifetime.isZero(), "ID lifetime must be greater than 0");
+
+ idLifetime = lifetime;
}
/** {@inheritDoc} */
@@ -143,7 +147,6 @@ public class StoredTransientIdGenerationStrategy extends AbstractIdentifiableIni
}
/** {@inheritDoc} */
- @Override
@Nonnull @NotEmpty public String generate(@Nonnull @NotEmpty final String relyingPartyId,
@Nonnull @NotEmpty final String principalName) throws SAMLException {
ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
@@ -163,11 +166,11 @@ public class StoredTransientIdGenerationStrategy extends AbstractIdentifiableIni
log.debug("Creating new transient ID '{}'", id);
- final long expiration = System.currentTimeMillis() + idLifetime;
+ final Instant expiration = Instant.now().plus(idLifetime);
int collisions = 0;
while (collisions < 5) {
- if (idStore.create(TransientIdParameters.CONTEXT, id, principalTokenId, expiration)) {
+ if (idStore.create(TransientIdParameters.CONTEXT, id, principalTokenId, expiration.toEpochMilli())) {
return id;
} else {
++collisions;
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnStatementToAssertion.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnStatementToAssertion.java
index d24eb80..6d72132 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnStatementToAssertion.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnStatementToAssertion.java
@@ -18,6 +18,7 @@
package net.shibboleth.idp.saml.saml2.profile.impl;
import java.security.Principal;
+import java.time.Duration;
import java.time.Instant;
import java.util.Set;
import java.util.function.Function;
@@ -91,7 +92,7 @@ public class AddAuthnStatementToAssertion extends BaseAddAuthenticationStatement
@NonnullAfterInit private Function<ProfileRequestContext,AuthnContextClassRefPrincipal> classRefLookupStrategy;
/** Strategy used to determine SessionNotOnOrAfter value to set. */
- @Nullable private Function<ProfileRequestContext,Long> sessionLifetimeLookupStrategy;
+ @Nullable private Function<ProfileRequestContext,Duration> sessionLifetimeLookupStrategy;
/** Constructor. */
public AddAuthnStatementToAssertion() {
@@ -127,7 +128,7 @@ public class AddAuthnStatementToAssertion extends BaseAddAuthenticationStatement
*
* @param strategy lookup strategy
*/
- public void setSessionLifetimeLookupStrategy(@Nullable final Function<ProfileRequestContext,Long> strategy) {
+ public void setSessionLifetimeLookupStrategy(@Nullable final Function<ProfileRequestContext,Duration> strategy) {
ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
sessionLifetimeLookupStrategy = strategy;
@@ -230,9 +231,9 @@ public class AddAuthnStatementToAssertion extends BaseAddAuthenticationStatement
}
if (sessionLifetimeLookupStrategy != null) {
- final Long lifetime = sessionLifetimeLookupStrategy.apply(profileRequestContext);
- if (lifetime != null && lifetime > 0) {
- statement.setSessionNotOnOrAfter(Instant.now().plusMillis(lifetime));
+ final Duration lifetime = sessionLifetimeLookupStrategy.apply(profileRequestContext);
+ if (lifetime != null && lifetime.toMillis() > 0) {
+ statement.setSessionNotOnOrAfter(Instant.now().plus(lifetime));
}
}
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/delegation/impl/PopulateDelegationContextTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/delegation/impl/PopulateDelegationContextTest.java
index c2ac2e7..89b4243 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/delegation/impl/PopulateDelegationContextTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/delegation/impl/PopulateDelegationContextTest.java
@@ -377,26 +377,6 @@ public class PopulateDelegationContextTest extends OpenSAMLInitBaseTestCase {
Assert.assertFalse(delegationContext.getSubjectConfirmationCredentials().isEmpty());
}
- @SuppressWarnings("deprecation")
- @Test
- public void testRequestedViaConditionsAllowedViaLegacyBoolean() throws Exception {
- authnRequest.setConditions(buildDelegationRequestConditions());
-
- browserSSOProfileConfig.setAllowingDelegation(true);
-
- action.initialize();
- final Event result = action.execute(rc);
- ActionTestingSupport.assertProceedEvent(result);
-
-
- DelegationContext delegationContext = prc.getSubcontext(DelegationContext.class);
- Assert.assertNotNull(delegationContext);
- Assert.assertEquals(delegationContext.isIssuingDelegatedAssertion(), true);
- Assert.assertEquals(delegationContext.getDelegationRequested(), DelegationRequest.REQUESTED_REQUIRED);
- Assert.assertNotNull(delegationContext.getSubjectConfirmationCredentials());
- Assert.assertFalse(delegationContext.getSubjectConfirmationCredentials().isEmpty());
- }
-
@Test
public void testRequiredNoKeyDescriptors() throws Exception {
samlMetadataContext.getRoleDescriptor().getKeyDescriptors().clear();
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnStatementToAssertionTest.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnStatementToAssertionTest.java
index a692c01..0074194 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnStatementToAssertionTest.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnStatementToAssertionTest.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.saml.saml2.profile.impl;
+import java.time.Duration;
import java.time.Instant;
import java.util.Arrays;
@@ -162,7 +163,7 @@ public class AddAuthnStatementToAssertionTest extends OpenSAMLInitBaseTestCase {
/** Test that the authentication statement is properly added. */
@Test public void testSessionNotOnOrAfter() {
final BrowserSSOProfileConfiguration ssoConfig = new BrowserSSOProfileConfiguration();
- ssoConfig.setMaximumSPSessionLifetime(60 * 60 * 1000);
+ ssoConfig.setMaximumSPSessionLifetime(Duration.ofHours(1));
ssoConfig.setSecurityConfiguration(new SecurityConfiguration());
prc.getSubcontext(RelyingPartyContext.class).setProfileConfig(ssoConfig);
diff --git a/idp-session-impl/src/main/java/net/shibboleth/idp/session/impl/ExtractActiveAuthenticationResults.java b/idp-session-impl/src/main/java/net/shibboleth/idp/session/impl/ExtractActiveAuthenticationResults.java
index 8e1d800..3cb1fb9 100644
--- a/idp-session-impl/src/main/java/net/shibboleth/idp/session/impl/ExtractActiveAuthenticationResults.java
+++ b/idp-session-impl/src/main/java/net/shibboleth/idp/session/impl/ExtractActiveAuthenticationResults.java
@@ -17,6 +17,7 @@
package net.shibboleth.idp.session.impl;
+import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
@@ -110,8 +111,8 @@ public class ExtractActiveAuthenticationResults extends AbstractAuthenticationAc
authenticationContext.setHintedName(session.getPrincipalName());
}
- final long maxAge = authenticationContext.getMaxAge();
final Instant now = Instant.now();
+ final Duration maxAge = authenticationContext.getMaxAge();
final List<AuthenticationResult> actives = new ArrayList<>();
for (final AuthenticationResult result : session.getAuthenticationResults()) {
@@ -124,7 +125,7 @@ public class ExtractActiveAuthenticationResults extends AbstractAuthenticationAc
}
if (descriptor.isResultActive(result)) {
- if (maxAge > 0 && result.getAuthenticationInstant().plusMillis(maxAge).isBefore(now)) {
+ if (maxAge != null && result.getAuthenticationInstant().plus(maxAge).isBefore(now)) {
log.debug("{} Authentication result {} exceeds maxAge setting, skipping it", getLogPrefix(),
result.getAuthenticationFlowId());
continue;
diff --git a/idp-session-impl/src/main/java/net/shibboleth/idp/session/impl/StorageBackedIdPSession.java b/idp-session-impl/src/main/java/net/shibboleth/idp/session/impl/StorageBackedIdPSession.java
index 7e1dc7b..862e2d0 100644
--- a/idp-session-impl/src/main/java/net/shibboleth/idp/session/impl/StorageBackedIdPSession.java
+++ b/idp-session-impl/src/main/java/net/shibboleth/idp/session/impl/StorageBackedIdPSession.java
@@ -254,8 +254,8 @@ public class StorageBackedIdPSession extends AbstractIdPSession {
if (flow != null) {
try {
if (!sessionManager.getStorageService().updateExpiration(getId(), result.getAuthenticationFlowId(),
- result.getLastActivityInstant().toEpochMilli() + flow.getInactivityTimeout()
- + AuthenticationFlowDescriptor.STORAGE_EXPIRATION_OFFSET)) {
+ result.getLastActivityInstant().plus(flow.getInactivityTimeout()).plus(
+ AuthenticationFlowDescriptor.STORAGE_EXPIRATION_OFFSET).toEpochMilli())) {
log.warn("Skipping update, AuthenticationResult for flow {} in session {} not found in storage",
flowId, getId());
}
@@ -585,13 +585,13 @@ public class StorageBackedIdPSession extends AbstractIdPSession {
boolean success = false;
do {
success = sessionManager.getStorageService().create(getId(), flowId, result, flow,
- result.getLastActivityInstant().toEpochMilli() + flow.getInactivityTimeout()
- + AuthenticationFlowDescriptor.STORAGE_EXPIRATION_OFFSET);
+ result.getLastActivityInstant().plus(flow.getInactivityTimeout()).plus(
+ AuthenticationFlowDescriptor.STORAGE_EXPIRATION_OFFSET).toEpochMilli());
if (!success) {
// The record already exists, so we need to overwrite via an update.
success = sessionManager.getStorageService().update(getId(), flowId, result, flow,
- result.getLastActivityInstant().toEpochMilli() + flow.getInactivityTimeout()
- + AuthenticationFlowDescriptor.STORAGE_EXPIRATION_OFFSET);
+ result.getLastActivityInstant().plus(flow.getInactivityTimeout()).plus(
+ AuthenticationFlowDescriptor.STORAGE_EXPIRATION_OFFSET).toEpochMilli());
}
} while (!success && attempts-- > 0);
diff --git a/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/StorageBackedSessionManagerTest.java b/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/StorageBackedSessionManagerTest.java
index 9d14028..bf80755 100644
--- a/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/StorageBackedSessionManagerTest.java
+++ b/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/StorageBackedSessionManagerTest.java
@@ -80,15 +80,15 @@ public class StorageBackedSessionManagerTest extends SessionManagerBaseTestCase
AuthenticationFlowDescriptor foo = new AuthenticationFlowDescriptor();
foo.setId("AuthenticationFlow/Foo");
- foo.setLifetime(60 * 1000);
- foo.setInactivityTimeout(60 * 1000);
+ foo.setLifetime(Duration.ofMinutes(1));
+ foo.setInactivityTimeout(Duration.ofMinutes(1));
foo.setResultSerializer(resultSerializer);
foo.initialize();
AuthenticationFlowDescriptor bar = new AuthenticationFlowDescriptor();
bar.setId("AuthenticationFlow/Bar");
- bar.setLifetime(60 * 1000);
- bar.setInactivityTimeout(60 * 1000);
+ bar.setLifetime(Duration.ofMinutes(1));
+ bar.setInactivityTimeout(Duration.ofMinutes(1));
bar.setResultSerializer(resultSerializer);
bar.initialize();
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list