[java-identity-provider] branch main updated: JSSH-9 - Rework IdentifierGenerationStrategy usage

Scott Cantor cantor.2 at osu.edu
Thu Oct 13 16:11:45 UTC 2022


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

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

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

The following commit(s) were added to refs/heads/main by this push:
     new 2a801e9ec JSSH-9 - Rework IdentifierGenerationStrategy usage
2a801e9ec is described below

commit 2a801e9ecc897496d9858f42f5169af270df932b
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Oct 13 12:11:42 2022 -0400

    JSSH-9 - Rework IdentifierGenerationStrategy usage
    
    https://shibboleth.atlassian.net/browse/JSSH-9
---
 .../cas/ticket/impl/EncodingTicketServiceTest.java | 25 ++++------
 .../src/test/resources/spring/test-flow-beans.xml  |  8 +++-
 .../net/shibboleth/idp/conf/security-system.xml    |  7 ++-
 .../shibboleth/idp/conf/session-manager-system.xml | 21 +++++++--
 .../idp/flows/authn/saml-authn-beans.xml           |  1 +
 .../flows/saml/logout/saml2-logoutprop-beans.xml   |  4 +-
 .../idp/test/flows/AbstractFlowTest.java           |  5 +-
 .../flows/saml1/SAML1AttributeQueryFlowTest.java   |  5 +-
 .../flows/saml2/SAML2AttributeQueryFlowTest.java   |  5 +-
 .../idp/profile/config/SecurityConfiguration.java  |  7 ++-
 ...IdentifierGenerationStrategyLookupFunction.java | 24 +++++++++-
 .../impl/StoredTransientIdGenerationStrategy.java  | 12 ++++-
 .../BaseIdPInitiatedSSORequestMessageDecoder.java  |  4 +-
 .../saml/saml2/profile/impl/AddAuthnRequest.java   |  4 +-
 .../idp/saml/session/impl/AddLogoutRequest.java    |  8 +---
 .../profile/impl/SessionManagerBaseTestCase.java   |  5 +-
 .../session/impl/SessionManagerBaseTestCase.java   |  6 +--
 .../StorageBackedIdPSessionSerializerTest.java     |  6 +--
 .../shibboleth/idp/ui/csrf/CSRFTokenManager.java   | 53 ++++++++++++++--------
 .../idp/ui/csrf/CSRFTokenManagerTest.java          | 42 +++++++++++------
 20 files changed, 165 insertions(+), 87 deletions(-)

diff --git a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketServiceTest.java b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketServiceTest.java
index cfd11da04..06875ef89 100644
--- a/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketServiceTest.java
+++ b/idp-cas-impl/src/test/java/net/shibboleth/idp/cas/ticket/impl/EncodingTicketServiceTest.java
@@ -17,8 +17,6 @@
 
 package net.shibboleth.idp.cas.ticket.impl;
 
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
 import java.time.Instant;
 import java.time.temporal.ChronoUnit;
 
@@ -29,8 +27,9 @@ import net.shibboleth.idp.cas.ticket.TicketIdentifierGenerationStrategy;
 import net.shibboleth.idp.cas.ticket.TicketState;
 import net.shibboleth.shared.security.DataSealer;
 import net.shibboleth.shared.security.IdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
+import net.shibboleth.shared.security.RandomIdentifierParameterSpec;
 import net.shibboleth.shared.security.impl.BasicKeystoreKeyStrategy;
-import net.shibboleth.shared.security.impl.RandomIdentifierGenerationStrategy;
 import net.shibboleth.shared.spring.resource.ResourceHelper;
 
 import org.apache.commons.codec.binary.Base32;
@@ -50,23 +49,16 @@ public class EncodingTicketServiceTest {
 
     private EncodingTicketService ticketService;
 
-    private IdentifierGenerationStrategy sessionIdGenerator = new RandomIdentifierGenerationStrategy(32);
+    private IdentifierGenerationStrategy sessionIdGenerator;
 
-    private IdentifierGenerationStrategy pgtIdGenerator = new TicketIdentifierGenerationStrategy("PGT", 32);
-
-    private SecureRandom secureRandom;
-
-
-    public EncodingTicketServiceTest() {
-        try {
-            secureRandom = SecureRandom.getInstance("SHA1PRNG");
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException("Secure random creation failed", e);
-        }
-    }
+    private IdentifierGenerationStrategy pgtIdGenerator;
 
     @BeforeClass
     public void setUp() throws Exception {
+        pgtIdGenerator = new TicketIdentifierGenerationStrategy("PGT", 32);
+        sessionIdGenerator = IdentifierGenerationStrategy.getInstance(ProviderType.RANDOM,
+                new RandomIdentifierParameterSpec(null, 32, null));
+        
         final BasicKeystoreKeyStrategy strategy = new BasicKeystoreKeyStrategy();
         strategy.setKeystoreResource(ResourceHelper.of(new ClassPathResource("credentials/sealer.jks")));
         strategy.setKeyVersionResource(ResourceHelper.of(new ClassPathResource("credentials/sealer.kver")));
@@ -77,7 +69,6 @@ public class EncodingTicketServiceTest {
         final Base32 codec = new Base32(0, null, false, (byte) '-');
         final DataSealer sealer = new DataSealer();
         sealer.setKeyStrategy(strategy);
-        sealer.setRandom(secureRandom);
         sealer.setEncoder(codec);
         sealer.setDecoder(codec);
         sealer.initialize();
diff --git a/idp-cas-impl/src/test/resources/spring/test-flow-beans.xml b/idp-cas-impl/src/test/resources/spring/test-flow-beans.xml
index 229835d43..155d3dfd0 100644
--- a/idp-cas-impl/src/test/resources/spring/test-flow-beans.xml
+++ b/idp-cas-impl/src/test/resources/spring/test-flow-beans.xml
@@ -50,8 +50,12 @@
         p:secure="false" />
 
     <bean id="shibboleth.SessionIDGenerator" destroy-method=""
-        class="net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy"
-        c:identifierSize="32" />
+            class="net.shibboleth.shared.security.IdentifierGenerationStrategy" factory-method="getInstance">
+        <constructor-arg>
+            <util:constant
+                static-field="net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType.SECURE" />
+        </constructor-arg>
+    </bean>
 
     <bean id="shibboleth.SessionManager"
           class="net.shibboleth.idp.session.impl.StorageBackedSessionManager"
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/security-system.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/security-system.xml
index 1c6262e38..6e6ebda29 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/security-system.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/security-system.xml
@@ -13,7 +13,12 @@
        default-destroy-method="destroy">
 
     <bean id="shibboleth.DefaultIdentifierGenerationStrategy"
-        class="net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy" />
+            class="net.shibboleth.shared.security.IdentifierGenerationStrategy" factory-method="getInstance">
+        <constructor-arg>
+            <util:constant
+                static-field="net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType.SECURE" />
+        </constructor-arg>
+    </bean>
 
     <!-- Principally used in relying-party.xml to define new security configurations. -->
 
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/session-manager-system.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/session-manager-system.xml
index ece70a82e..3832885c9 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/session-manager-system.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/conf/session-manager-system.xml
@@ -12,9 +12,24 @@
        default-init-method="initialize"
        default-destroy-method="destroy">
 
-    <bean id="shibboleth.SessionIDGenerator"
-        class="net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy"
-        c:identifierSize="%{idp.session.idSize:32}" />
+    <bean id="shibboleth.SessionIDGenerator" destroy-method=""
+            class="net.shibboleth.shared.security.IdentifierGenerationStrategy" factory-method="getInstance">
+        <constructor-arg>
+            <util:constant
+                static-field="net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType.SECURE" />
+        </constructor-arg>
+        <constructor-arg>
+            <bean class="net.shibboleth.shared.security.RandomIdentifierParameterSpec"
+                    c:identifierSize="%{idp.session.idSize:32}">
+                <constructor-arg name="source">
+                    <null/>
+                </constructor-arg>
+                <constructor-arg name="identifierEncoding">
+                    <null/>
+                </constructor-arg>
+            </bean>
+        </constructor-arg>
+    </bean>
 
     <!-- Dummy bean for compatibility, this is no longer a supported extensions point. -->
     <bean id="shibboleth.DefaultSessionTypeProtocolMap" lazy-init="true"
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml
index 6b4557dee..8c450adef 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/authn/saml-authn-beans.xml
@@ -157,6 +157,7 @@
             p:issuerLookupStrategy-ref="shibboleth.ResponderIdLookup.Simple">
         <property name="identifierGeneratorLookupStrategy">
             <bean class="net.shibboleth.idp.profile.config.navigate.IdentifierGenerationStrategyLookupFunction"
+                p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver"
                 p:defaultIdentifierGenerationStrategy-ref="shibboleth.DefaultIdentifierGenerationStrategy" />
         </property>
     </bean>
diff --git a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/logout/saml2-logoutprop-beans.xml b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/logout/saml2-logoutprop-beans.xml
index 4a8fd4cfe..8e635832a 100644
--- a/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/logout/saml2-logoutprop-beans.xml
+++ b/idp-conf-impl/src/main/resources/net/shibboleth/idp/flows/saml/logout/saml2-logoutprop-beans.xml
@@ -59,12 +59,12 @@
         p:bestMatchCriterionLookupStrategy-ref="BestMatchCriterionLookupStrategy" />
     <bean id="BestMatchCriterionLookupStrategy" class="net.shibboleth.idp.saml.session.impl.BestMatchLocationLookupStrategy" />
 
-    <bean id="AddLogoutRequest"
-        class="net.shibboleth.idp.saml.session.impl.AddLogoutRequest" scope="prototype"
+    <bean id="AddLogoutRequest" class="net.shibboleth.idp.saml.session.impl.AddLogoutRequest" scope="prototype"
             p:overwriteExisting="true"
             p:issuerLookupStrategy-ref="shibboleth.ResponderIdLookup.Simple">
         <property name="identifierGeneratorLookupStrategy">
             <bean class="net.shibboleth.idp.profile.config.navigate.IdentifierGenerationStrategyLookupFunction"
+                p:relyingPartyConfigurationResolver-ref="shibboleth.RelyingPartyConfigurationResolver"
                 p:defaultIdentifierGenerationStrategy-ref="shibboleth.DefaultIdentifierGenerationStrategy" />
         </property>
     </bean>
diff --git a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/AbstractFlowTest.java b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/AbstractFlowTest.java
index 97f40f624..218584f46 100644
--- a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/AbstractFlowTest.java
+++ b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/AbstractFlowTest.java
@@ -78,7 +78,7 @@ import net.shibboleth.idp.test.TestEnvironmentApplicationContextInitializer;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.security.IdentifierGenerationStrategy;
-import net.shibboleth.shared.security.impl.Type4UUIDIdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
 import net.shibboleth.shared.servlet.impl.HttpServletRequestResponseContext;
 import net.shibboleth.shared.spring.security.factory.X509CertificateFactoryBean;
 import net.shibboleth.shared.xml.ParserPool;
@@ -172,7 +172,7 @@ public abstract class AbstractFlowTest extends AbstractTestNGSpringContextTests
     @NonnullAfterInit protected static UnmarshallerFactory unmarshallerFactory;
 
     /** UUID identifier generation strategy. */
-    @Nonnull protected IdentifierGenerationStrategy idGenerator = new Type4UUIDIdentifierGenerationStrategy();
+    @Nonnull protected IdentifierGenerationStrategy idGenerator;
 
     /** IdP credential wired via test/test-beans.xml. */
     @Qualifier("test.idp.Credential") @Autowired protected Credential idpCredential;
@@ -228,6 +228,7 @@ public abstract class AbstractFlowTest extends AbstractTestNGSpringContextTests
         builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory();
         marshallerFactory = XMLObjectProviderRegistrySupport.getMarshallerFactory();
         unmarshallerFactory = XMLObjectProviderRegistrySupport.getUnmarshallerFactory();
+        idGenerator = IdentifierGenerationStrategy.getInstance(ProviderType.UUID);
     }
 
     /**
diff --git a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml1/SAML1AttributeQueryFlowTest.java b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml1/SAML1AttributeQueryFlowTest.java
index 88f24f6c4..0263a64ff 100644
--- a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml1/SAML1AttributeQueryFlowTest.java
+++ b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml1/SAML1AttributeQueryFlowTest.java
@@ -24,7 +24,8 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import net.shibboleth.idp.saml.xml.SAMLConstants;
-import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
 import net.shibboleth.shared.xml.SerializeSupport;
 
 import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
@@ -147,7 +148,7 @@ public class SAML1AttributeQueryFlowTest extends AbstractSAML1FlowTest {
         final Request attributeQuery = SAML1ActionTestingSupport.buildAttributeQueryRequest(subject);
         attributeQuery.setIssueInstant(Instant.now());
         attributeQuery.getAttributeQuery().setResource(SP_ENTITY_ID);
-        attributeQuery.setID(new SecureRandomIdentifierGenerationStrategy().generateIdentifier());
+        attributeQuery.setID(IdentifierGenerationStrategy.getInstance(ProviderType.SECURE).generateIdentifier());
         
         if (includeDesignators) {
             final SAMLObjectBuilder<AttributeDesignator> designatorBuilder = (SAMLObjectBuilder<AttributeDesignator>)
diff --git a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml2/SAML2AttributeQueryFlowTest.java b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml2/SAML2AttributeQueryFlowTest.java
index ea1abbf79..64d9a6e69 100644
--- a/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml2/SAML2AttributeQueryFlowTest.java
+++ b/idp-conf/src/test/java/net/shibboleth/idp/test/flows/saml2/SAML2AttributeQueryFlowTest.java
@@ -23,7 +23,8 @@ import java.time.Instant;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
-import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
 import net.shibboleth.shared.xml.SerializeSupport;
 
 import org.opensaml.core.xml.XMLObjectBuilder;
@@ -153,7 +154,7 @@ public class SAML2AttributeQueryFlowTest extends AbstractSAML2FlowTest {
         final AttributeQuery attributeQuery = SAML2ActionTestingSupport.buildAttributeQueryRequest(subject);
         attributeQuery.setIssueInstant(Instant.now());
         attributeQuery.getIssuer().setValue(SP_ENTITY_ID);
-        attributeQuery.setID(new SecureRandomIdentifierGenerationStrategy().generateIdentifier());
+        attributeQuery.setID(IdentifierGenerationStrategy.getInstance(ProviderType.SECURE).generateIdentifier());
 
         if (includeDesignators) {
             final SAMLObjectBuilder<Attribute> designatorBuilder = (SAMLObjectBuilder<Attribute>)
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 6b7cb27f7..095fccd44 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
@@ -24,7 +24,7 @@ import javax.annotation.Nullable;
 
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.security.IdentifierGenerationStrategy;
-import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
 
 import org.opensaml.security.httpclient.HttpClientSecurityConfiguration;
 import org.opensaml.security.x509.tls.ClientTLSValidationConfiguration;
@@ -63,12 +63,11 @@ public class SecurityConfiguration {
     /**
      * Constructor.
      * 
-     * Initializes the clock skew to 5 minutes and the identifier generator to
-     * {@link SecureRandomIdentifierGenerationStrategy} using the SHA1PRNG algorithm.
+     * Initializes the clock skew to 5 minutes and the identifier generator to {@link ProviderType#SECURE}.
      */
     public SecurityConfiguration() {
         clockSkew = Duration.ofMinutes(5);
-        idGenerator = new SecureRandomIdentifierGenerationStrategy();
+        idGenerator = IdentifierGenerationStrategy.getInstance(ProviderType.SECURE);
     }
 
     /**
diff --git a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/navigate/IdentifierGenerationStrategyLookupFunction.java b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/navigate/IdentifierGenerationStrategyLookupFunction.java
index 010d6e1d1..82c00b137 100644
--- a/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/navigate/IdentifierGenerationStrategyLookupFunction.java
+++ b/idp-profile-api/src/main/java/net/shibboleth/idp/profile/config/navigate/IdentifierGenerationStrategyLookupFunction.java
@@ -23,6 +23,7 @@ import net.shibboleth.idp.profile.config.ProfileConfiguration;
 import net.shibboleth.idp.profile.config.SecurityConfiguration;
 import net.shibboleth.idp.profile.context.RelyingPartyContext;
 import net.shibboleth.idp.profile.context.navigate.AbstractRelyingPartyLookupFunction;
+import net.shibboleth.idp.relyingparty.RelyingPartyConfigurationResolver;
 import net.shibboleth.shared.security.IdentifierGenerationStrategy;
 
 import org.opensaml.profile.context.ProfileRequestContext;
@@ -36,6 +37,18 @@ import org.opensaml.profile.context.ProfileRequestContext;
 public class IdentifierGenerationStrategyLookupFunction
         extends AbstractRelyingPartyLookupFunction<IdentifierGenerationStrategy> {
     
+    /** A resolver for default security configurations. */
+    @Nullable private RelyingPartyConfigurationResolver rpResolver;
+
+    /**
+     * Set the resolver for default security configurations.
+     * 
+     * @param resolver the resolver to use
+     */
+    public void setRelyingPartyConfigurationResolver(@Nullable final RelyingPartyConfigurationResolver resolver) {
+        rpResolver = resolver;
+    }
+
     /** Default strategy to return. */
     @Nullable private IdentifierGenerationStrategy defaultGenerator;
     
@@ -63,7 +76,16 @@ public class IdentifierGenerationStrategyLookupFunction
                 }
             }
         }
-        
+
+        // Check for a per-profile default (relying party independent) config.
+        if (input != null && rpResolver != null) {
+            final SecurityConfiguration defaultConfig =
+                    rpResolver.getDefaultSecurityConfiguration(input.getProfileId());
+            if (defaultConfig != null && defaultConfig.getIdGenerator() != null) {
+                return defaultConfig.getIdGenerator();
+            }
+        }
+
         return defaultGenerator;
     }
 
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 324ee9ad9..169bd900d 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,6 +18,8 @@
 package net.shibboleth.idp.saml.nameid.impl;
 
 import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
 import java.time.Duration;
 import java.time.Instant;
 
@@ -35,7 +37,8 @@ import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponen
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.security.IdentifierGenerationStrategy;
-import net.shibboleth.shared.security.impl.RandomIdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
+import net.shibboleth.shared.security.RandomIdentifierParameterSpec;
 
 /**
  * Generates transients using a {@link StorageService} to manage the reverse mappings.
@@ -137,7 +140,12 @@ public class StoredTransientIdGenerationStrategy extends AbstractIdentifiableIni
         }
 
         if (idGenerator == null) {
-            idGenerator = new RandomIdentifierGenerationStrategy(idSize);
+            try {
+                idGenerator = IdentifierGenerationStrategy.getInstance(ProviderType.RANDOM,
+                        new RandomIdentifierParameterSpec(null, idSize, null));
+            } catch (final InvalidAlgorithmParameterException|NoSuchAlgorithmException e) {
+                throw new ComponentInitializationException(e);
+            }
         }
     }
     
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/profile/impl/BaseIdPInitiatedSSORequestMessageDecoder.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/profile/impl/BaseIdPInitiatedSSORequestMessageDecoder.java
index 20c9cf26c..0e9b80892 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/profile/impl/BaseIdPInitiatedSSORequestMessageDecoder.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/profile/impl/BaseIdPInitiatedSSORequestMessageDecoder.java
@@ -26,7 +26,7 @@ import jakarta.servlet.http.HttpServletRequest;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.primitive.StringSupport;
 import net.shibboleth.shared.security.IdentifierGenerationStrategy;
-import net.shibboleth.shared.security.impl.Type4UUIDIdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
 
 import org.opensaml.messaging.decoder.MessageDecodingException;
 import org.opensaml.messaging.decoder.servlet.AbstractHttpServletRequestMessageDecoder;
@@ -65,7 +65,7 @@ public abstract class BaseIdPInitiatedSSORequestMessageDecoder extends AbstractH
     @Nonnull private final Logger protocolMessageLog = LoggerFactory.getLogger("PROTOCOL_MESSAGE");
     
     /** ID generator. */
-    @Nonnull private final IdentifierGenerationStrategy idGenerator = new Type4UUIDIdentifierGenerationStrategy();
+    @Nonnull private final IdentifierGenerationStrategy idGenerator = IdentifierGenerationStrategy.getInstance(ProviderType.UUID);
     
     /**
      * Get an optional {@link BindingDescriptor} to inject into
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java
index 08c338e2c..3ae44433f 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/saml2/profile/impl/AddAuthnRequest.java
@@ -50,6 +50,7 @@ import org.slf4j.LoggerFactory;
 import net.shibboleth.idp.authn.AbstractAuthenticationAction;
 import net.shibboleth.idp.authn.context.AuthenticationContext;
 import net.shibboleth.idp.profile.IdPEventIds;
+import net.shibboleth.idp.profile.config.navigate.IdentifierGenerationStrategyLookupFunction;
 import net.shibboleth.idp.profile.context.RelyingPartyContext;
 import net.shibboleth.idp.saml.authn.principal.AuthnContextClassRefPrincipal;
 import net.shibboleth.idp.saml.authn.principal.AuthnContextDeclRefPrincipal;
@@ -57,7 +58,6 @@ import net.shibboleth.idp.saml.saml2.profile.config.BrowserSSOProfileConfigurati
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.security.IdentifierGenerationStrategy;
-import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
 
 /**
  * Action that creates an {@link AuthnRequest} and sets it as the message returned by
@@ -101,7 +101,7 @@ public class AddAuthnRequest extends AbstractAuthenticationAction {
     /** Constructor. */
     public AddAuthnRequest() {
         // Default strategy is a 16-byte secure random source.
-        idGeneratorLookupStrategy = prc -> new SecureRandomIdentifierGenerationStrategy();
+        idGeneratorLookupStrategy = new IdentifierGenerationStrategyLookupFunction();
         
         // Fool the parent class into looking above instead of below the PRC for the context.
         setAuthenticationContextLookupStrategy(new ParentContextLookup<>(AuthenticationContext.class));
diff --git a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/session/impl/AddLogoutRequest.java b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/session/impl/AddLogoutRequest.java
index e38a9b24a..41e7788f7 100644
--- a/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/session/impl/AddLogoutRequest.java
+++ b/idp-saml-impl/src/main/java/net/shibboleth/idp/saml/session/impl/AddLogoutRequest.java
@@ -43,11 +43,11 @@ import org.opensaml.saml.saml2.core.SessionIndex;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import net.shibboleth.idp.profile.config.navigate.IdentifierGenerationStrategyLookupFunction;
 import net.shibboleth.idp.saml.session.SAML2SPSession;
 import net.shibboleth.idp.session.context.LogoutPropagationContext;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.security.IdentifierGenerationStrategy;
-import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
 
 /**
  * Action that creates a {@link LogoutRequest} based on an {@link SAML2SPSession} in a
@@ -95,11 +95,7 @@ public class AddLogoutRequest extends AbstractProfileAction {
     /** Constructor. */
     public AddLogoutRequest() {
         // Default strategy is a 16-byte secure random source.
-        idGeneratorLookupStrategy = new Function<>() {
-            public IdentifierGenerationStrategy apply(final ProfileRequestContext input) {
-                return new SecureRandomIdentifierGenerationStrategy();
-            }
-        };
+        idGeneratorLookupStrategy = new IdentifierGenerationStrategyLookupFunction();
         
         logoutPropContextLookupStrategy = new ChildContextLookup<>(LogoutPropagationContext.class);
         includeSessionIndex = true;
diff --git a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/SessionManagerBaseTestCase.java b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/SessionManagerBaseTestCase.java
index d2a0bb126..20ff6810b 100644
--- a/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/SessionManagerBaseTestCase.java
+++ b/idp-saml-impl/src/test/java/net/shibboleth/idp/saml/saml2/profile/impl/SessionManagerBaseTestCase.java
@@ -29,7 +29,8 @@ import net.shibboleth.idp.session.impl.StorageBackedSessionManager;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.net.CookieManager;
-import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
 import net.shibboleth.shared.servlet.impl.HttpServletRequestResponseContext;
 import net.shibboleth.shared.servlet.impl.ThreadLocalHttpServletRequestProxy;
 import net.shibboleth.shared.servlet.impl.ThreadLocalHttpServletResponseProxy;
@@ -67,7 +68,7 @@ public class SessionManagerBaseTestCase extends OpenSAMLInitBaseTestCase {
         sessionManager = new StorageBackedSessionManager();
         sessionManager.setSessionTimeout(Duration.ofSeconds(15));
         sessionManager.setStorageService(storageService);
-        sessionManager.setIDGenerator(new SecureRandomIdentifierGenerationStrategy());
+        sessionManager.setIDGenerator(IdentifierGenerationStrategy.getInstance(ProviderType.SECURE));
         sessionManager.setHttpServletRequestSupplier(new Supplier<>() {public HttpServletRequest get() {return requestProxy;}});
         sessionManager.setCookieManager(cookieManager);
         sessionManager.setId("Test Session Manager");
diff --git a/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/SessionManagerBaseTestCase.java b/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/SessionManagerBaseTestCase.java
index 97055453a..2e5dbbaba 100644
--- a/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/SessionManagerBaseTestCase.java
+++ b/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/SessionManagerBaseTestCase.java
@@ -25,11 +25,11 @@ import jakarta.servlet.http.Cookie;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import net.shibboleth.idp.session.SessionException;
-import net.shibboleth.idp.session.impl.StorageBackedSessionManager;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.net.CookieManager;
-import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
 import net.shibboleth.shared.servlet.impl.HttpServletRequestResponseContext;
 import net.shibboleth.shared.servlet.impl.ThreadLocalHttpServletRequestProxy;
 import net.shibboleth.shared.servlet.impl.ThreadLocalHttpServletResponseProxy;
@@ -67,7 +67,7 @@ public class SessionManagerBaseTestCase extends OpenSAMLInitBaseTestCase {
         sessionManager = new StorageBackedSessionManager();
         sessionManager.setSessionTimeout(Duration.ofSeconds(15));
         sessionManager.setStorageService(storageService);
-        sessionManager.setIDGenerator(new SecureRandomIdentifierGenerationStrategy());
+        sessionManager.setIDGenerator(IdentifierGenerationStrategy.getInstance(ProviderType.SECURE));
         sessionManager.setHttpServletRequestSupplier(new Supplier<>() {public HttpServletRequest get() {return requestProxy;}});
         sessionManager.setCookieManager(cookieManager);
         sessionManager.setId("Test Session Manager");
diff --git a/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/StorageBackedIdPSessionSerializerTest.java b/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/StorageBackedIdPSessionSerializerTest.java
index 3bf0b3097..4146aa6a2 100644
--- a/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/StorageBackedIdPSessionSerializerTest.java
+++ b/idp-session-impl/src/test/java/net/shibboleth/idp/session/impl/StorageBackedIdPSessionSerializerTest.java
@@ -40,9 +40,9 @@ import net.shibboleth.idp.session.BasicSPSession;
 import net.shibboleth.idp.session.SPSessionSerializerRegistry;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.net.CookieManager;
-import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
 import net.shibboleth.shared.servlet.impl.ThreadLocalHttpServletRequestProxy;
-import net.shibboleth.shared.servlet.impl.ThreadLocalHttpServletResponseProxy;
 
 /** {@link StorageBackedIdPSessionSerializer} unit test. */
 @SuppressWarnings("javadoc")
@@ -75,7 +75,7 @@ public class StorageBackedIdPSessionSerializerTest {
         
         manager = new StorageBackedSessionManager();
         manager.setStorageService(storageService);
-        manager.setIDGenerator(new SecureRandomIdentifierGenerationStrategy());
+        manager.setIDGenerator(IdentifierGenerationStrategy.getInstance(ProviderType.SECURE));
         final HttpServletRequest requestProxy = new ThreadLocalHttpServletRequestProxy();
         manager.setHttpServletRequestSupplier(new Supplier<>() {public HttpServletRequest get() {return requestProxy;}});
         manager.setCookieManager(cookieManager);
diff --git a/idp-ui/src/main/java/net/shibboleth/idp/ui/csrf/CSRFTokenManager.java b/idp-ui/src/main/java/net/shibboleth/idp/ui/csrf/CSRFTokenManager.java
index 8237c0a26..bd9cad79e 100644
--- a/idp-ui/src/main/java/net/shibboleth/idp/ui/csrf/CSRFTokenManager.java
+++ b/idp-ui/src/main/java/net/shibboleth/idp/ui/csrf/CSRFTokenManager.java
@@ -17,6 +17,8 @@
 
 package net.shibboleth.idp.ui.csrf;
 
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
 import java.util.function.BiPredicate;
 
 import javax.annotation.Nonnull;
@@ -25,15 +27,18 @@ import javax.annotation.concurrent.ThreadSafe;
 
 import net.shibboleth.idp.ui.csrf.impl.SimpleCSRFToken;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.component.AbstractInitializableComponent;
+import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.security.IdentifierGenerationStrategy;
-import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
+import net.shibboleth.shared.security.RandomIdentifierParameterSpec;
 
 /**
  * A thread-safe helper class for dealing with cross-site request forgery tokens. 
  */
 @ThreadSafe
-public final class CSRFTokenManager {
+public final class CSRFTokenManager extends AbstractInitializableComponent {
         
     /** The name of the HTTP parameter that contains the anti-csrf token.*/
    @Nonnull private String csrfParameterName;
@@ -44,16 +49,9 @@ public final class CSRFTokenManager {
    /** Predicate to validate the CSRF token.*/
    @Nonnull private BiPredicate<CSRFToken,String> csrfTokenValidationPredicate;
     
-    /**
-     * public Constructor.
-     * 
-     * <p>A 20 byte {@link SecureRandomIdentifierGenerationStrategy} is 
-     * default to guarantee a strong token entropy.</p>
-     *
-     */
+    /** Constructor. */
     public CSRFTokenManager() {
         csrfParameterName = "csrf_token";
-        tokenGenerationStrategy = new SecureRandomIdentifierGenerationStrategy(20);
         csrfTokenValidationPredicate = new DefaultCSRFTokenValidationPredicate();
     }
     
@@ -62,7 +60,8 @@ public final class CSRFTokenManager {
      * 
      * @param tokenStrategy CSRF token generation strategy
      */
-    public void setTokenGenerationStrategy(@Nonnull final IdentifierGenerationStrategy tokenStrategy) {          
+    public void setTokenGenerationStrategy(@Nonnull final IdentifierGenerationStrategy tokenStrategy) {
+        checkSetterPreconditions();
         tokenGenerationStrategy = Constraint.isNotNull(tokenStrategy, "tokenGenerationStrategy cannot be null");
     }
     
@@ -71,8 +70,8 @@ public final class CSRFTokenManager {
      * 
      * @param tokenValidationPredicate the CSRF token validation predicate.
      */
-    public void setCsrfTokenValidationPredicate(
-            @Nonnull final BiPredicate<CSRFToken,String> tokenValidationPredicate) {       
+    public void setCsrfTokenValidationPredicate(@Nonnull final BiPredicate<CSRFToken,String> tokenValidationPredicate) {
+        checkSetterPreconditions();
         csrfTokenValidationPredicate = Constraint.isNotNull(tokenValidationPredicate, 
                 "CSRF token validation predicate can not be null");
     }
@@ -82,17 +81,34 @@ public final class CSRFTokenManager {
      * 
      * @param parameterName CSRF parameter name
      */
-    public void setCsrfParameterName(@Nonnull @NotEmpty final String parameterName) {           
+    public void setCsrfParameterName(@Nonnull @NotEmpty final String parameterName) {
+        checkSetterPreconditions();
         csrfParameterName = Constraint.isNotEmpty(parameterName, "CsrfParameterName cannot be null or empty");
     }
-    
+
+    /** {@inheritDoc} */
+    @Override
+    protected void doInitialize() throws ComponentInitializationException {
+        super.doInitialize();
+        
+        if (tokenGenerationStrategy == null) {
+            try {
+                tokenGenerationStrategy = IdentifierGenerationStrategy.getInstance(ProviderType.SECURE,
+                        new RandomIdentifierParameterSpec(null, 20, null));
+            } catch (final InvalidAlgorithmParameterException | NoSuchAlgorithmException e) {
+                throw new ComponentInitializationException(e);
+            }
+        }
+    }
+
     /**
      * Generate a {@link CSRFToken} using the token generation strategy derived token value. Set
      * the HTTP parameter name from the <code>csrfParameterName</code> field.
      * 
      * @return a CSRF token
      */
-    @Nonnull public CSRFToken generateCSRFToken() {       
+    @Nonnull public CSRFToken generateCSRFToken() {
+        checkComponentActive();
         return new SimpleCSRFToken(tokenGenerationStrategy.generateIdentifier(),csrfParameterName);        
         
     }
@@ -105,7 +121,8 @@ public final class CSRFTokenManager {
      * @return true iff the CSRF token value matches the request CSRF token. False if they do not match.
      */
     public boolean isValidCSRFToken(@Nullable final CSRFToken csrfToken, 
-            @Nullable final String requestCsrfToken) {        
+            @Nullable final String requestCsrfToken) {
+        checkComponentActive();
         return csrfTokenValidationPredicate.test(csrfToken, requestCsrfToken);       
     }
     
@@ -132,4 +149,4 @@ public final class CSRFTokenManager {
         
     }
 
-}
+}
\ No newline at end of file
diff --git a/idp-ui/src/test/java/net/shibboleth/idp/ui/csrf/CSRFTokenManagerTest.java b/idp-ui/src/test/java/net/shibboleth/idp/ui/csrf/CSRFTokenManagerTest.java
index 821fa5222..48dabd32d 100644
--- a/idp-ui/src/test/java/net/shibboleth/idp/ui/csrf/CSRFTokenManagerTest.java
+++ b/idp-ui/src/test/java/net/shibboleth/idp/ui/csrf/CSRFTokenManagerTest.java
@@ -22,8 +22,10 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import net.shibboleth.idp.ui.csrf.impl.SimpleCSRFToken;
+import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.ConstraintViolationException;
-import net.shibboleth.shared.security.impl.SecureRandomIdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy;
+import net.shibboleth.shared.security.IdentifierGenerationStrategy.ProviderType;
 
 /**
  * Tests for the {@link CSRFTokenManager}.
@@ -33,36 +35,47 @@ public class CSRFTokenManagerTest {
     /** Test token manager instance.*/
     private CSRFTokenManager manager;
     
-    
-    @BeforeMethod public void setup() {
+    /**
+     * Test setup. 
+     * @throws ComponentInitializationException 
+     */
+    @BeforeMethod public void setup() throws ComponentInitializationException {
         manager = new CSRFTokenManager();
+        manager.initialize();
     }
     
     /** Test setting an invalid csrf parameter name, which should trigger an exception.*/
-    @Test(expectedExceptions=ConstraintViolationException.class) public void testSetNullCsrfParameterName() {       
+    @Test(expectedExceptions=ConstraintViolationException.class) public void testSetNullCsrfParameterName() {
+        manager = new CSRFTokenManager();
         manager.setCsrfParameterName(null);
     }
     
     /** Test setting a valid csrf parameter name, which should not trigger an exception.*/
-    @Test public void testSetCsrfParameterName() {       
+    @Test public void testSetCsrfParameterName() {
+        manager = new CSRFTokenManager();
         manager.setCsrfParameterName("csrf_token");
     }
     
     /** Test setting an invalid token generation strategy, which should trigger an exception.*/
-    @Test(expectedExceptions=ConstraintViolationException.class) public void testSetNullTokenGenerationStrategy() {       
+    @Test(expectedExceptions=ConstraintViolationException.class) public void testSetNullTokenGenerationStrategy() {
+        manager = new CSRFTokenManager();
         manager.setTokenGenerationStrategy(null);
     }
     
     /** Test setting a valid token generation strategy, which should not trigger an exception.*/
-    @Test public void testSetTokenGenerationStrategy() {       
-        manager.setTokenGenerationStrategy(new SecureRandomIdentifierGenerationStrategy(20));
+    @Test public void testSetTokenGenerationStrategy() {
+        manager = new CSRFTokenManager();
+        manager.setTokenGenerationStrategy(IdentifierGenerationStrategy.getInstance(ProviderType.SECURE));
     }
     
-    /** Test what happens if you add a custom validation predicate that always returns false.*/
-    @Test public void testCustomTokenValidationPredicate() {
+    /** Test what happens if you add a custom validation predicate that always returns false.
+     * @throws ComponentInitializationException */
+    @Test public void testCustomTokenValidationPredicate() throws ComponentInitializationException {
+        manager = new CSRFTokenManager();
         manager.setCsrfTokenValidationPredicate((stored,request) -> {
             return false;
         });
+        manager.initialize();
         Assert.assertFalse(manager.isValidCSRFToken(new SimpleCSRFToken("token", "param"), "does-not-matter"));
     }
     
@@ -75,11 +88,14 @@ public class CSRFTokenManagerTest {
     
     }
     
-    /** Test token generation using a customised instantiation of the token manager.*/
-    @Test public void testCustomisedTokenGeneration() {
+    /** Test token generation using a customised instantiation of the token manager.
+     * @throws ComponentInitializationException */
+    @Test public void testCustomisedTokenGeneration() throws ComponentInitializationException {
        
+        manager = new CSRFTokenManager();
         manager.setCsrfParameterName("test_name");
-        manager.setTokenGenerationStrategy(new SecureRandomIdentifierGenerationStrategy(40));
+        manager.setTokenGenerationStrategy(IdentifierGenerationStrategy.getInstance(ProviderType.SECURE));
+        manager.initialize();
         CSRFToken token = manager.generateCSRFToken();
         Assert.assertNotNull(token);
         Assert.assertEquals("test_name",token.getParameterName());

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


More information about the commits mailing list