[java-plugin-shibd-saml] branch dev/StateMgmtWIP updated: Bug fixing, getting unit tests working again.

Codeberg noreply at shibboleth.net
Tue Apr 28 15:18:09 UTC 2026


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

codeberg pushed a commit to branch dev/StateMgmtWIP
in repository java-plugin-shibd-saml.

View the commit online:
https://codeberg.org/Shibboleth/java-plugin-shibd-saml/commit/5023eaa145603b8f65d4fc7186c7ba0e0c4012e1

The following commit(s) were added to refs/heads/dev/StateMgmtWIP by this push:
     new 5023eaa  Bug fixing, getting unit tests working again.
5023eaa is described below

commit 5023eaa145603b8f65d4fc7186c7ba0e0c4012e1
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Tue Apr 28 11:17:58 2026 -0400

    Bug fixing, getting unit tests working again.
---
 .../shibboleth/idp/flows/sp/saml2-common-beans.xml |  1 +
 .../flows/saml2/SAML2SessionInitiatorFlowTest.java | 55 +++--------------
 ...MLEnvironmentApplicationContextInitializer.java |  1 +
 .../shibboleth/idp/module/conf/sp/saml.properties  | 72 ++++++++++++++++++++++
 4 files changed, 84 insertions(+), 45 deletions(-)

diff --git a/sp-saml-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/saml2-common-beans.xml b/sp-saml-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/saml2-common-beans.xml
index 1c725e9..d996699 100644
--- a/sp-saml-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/saml2-common-beans.xml
+++ b/sp-saml-conf-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/sp/saml2-common-beans.xml
@@ -167,6 +167,7 @@
 
     <bean id="PreserveRelayState"
         class="net.shibboleth.sp.saml.saml2.profile.impl.PreserveRelayState" scope="prototype"
+        p:createOutputObjects="true"
         p:errorFatal="%{sp.stateToken.errorsFatal:false}" />
 
     <bean id="messageEncoderFactory" class="net.shibboleth.idp.saml.profile.impl.SpringAwareMessageEncoderFactory" />
diff --git a/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/SAML2SessionInitiatorFlowTest.java b/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/SAML2SessionInitiatorFlowTest.java
index 07f24b2..e3c2ace 100644
--- a/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/SAML2SessionInitiatorFlowTest.java
+++ b/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/SAML2SessionInitiatorFlowTest.java
@@ -57,7 +57,6 @@ import net.shibboleth.sp.messaging.RemotedHttpServletRequest;
 import net.shibboleth.sp.messaging.RemotedHttpServletResponse;
 import net.shibboleth.sp.profile.InitiatorConstants;
 import net.shibboleth.sp.profile.SPConstants;
-import net.shibboleth.sp.profile.impl.IssueCorrelationCookie;
 import net.shibboleth.sp.saml.saml2.profile.SAML2InitiatorConstants;
 
 /**
@@ -194,37 +193,6 @@ public class SAML2SessionInitiatorFlowTest extends AbstractSPFlowTest {
         assertFalse(req.isPassive());
     }
     
-    /**
-     * Test simple success case with preset relay state.
-     * 
-     * @throws IOException 
-     * @throws MessageDecodingException 
-     */
-    @Test
-    public void testSimpleWithState() throws IOException, MessageDecodingException {
-        setDefaultAuth();
-        
-        final DDF input = new DDF(null).structure();
-        input.addmember(RemotedHttpServletRequest.STRUCTURE_NAME).structure();
-        input.addmember(InitiatorConstants.RESPONSE_URL).string(RESPONSE_URL);
-        input.addmember(SPConstants.STATE).string("foostate");
-        setApplicationRequest(APPLICATION_ID, input);
-
-        final FlowExecutionResult result = flowExecutor.launchExecution(FLOW_ID, null, externalContext);
-        assertFlowExecutionResult(result, FLOW_ID);
-        assertFlowExecutionOutcome(result.getOutcome());
-        
-        assertOutputMessageSuccess(result);
-        final AuthnRequest req = validateOutputMessage(result, null);
-        Assert.assertEquals(req.getAssertionConsumerServiceURL(), RESPONSE_URL);
-        Assert.assertEquals(req.getProtocolBinding(), SAMLConstants.SAML2_POST_BINDING_URI);
-        Assert.assertNull(req.getSubject());
-        Assert.assertNull(req.getRequestedAuthnContext());
-        Assert.assertNull(req.getScoping());
-        assertFalse(req.isForceAuthn());
-        assertFalse(req.isPassive());
-    }
-    
     /**
      * Test legacy response URL success case picking first URL.
      * 
@@ -579,8 +547,8 @@ public class SAML2SessionInitiatorFlowTest extends AbstractSPFlowTest {
      * 
      * @throws MessageDecodingException
      */
-    @Nonnull private AuthnRequest validateOutputMessage(@Nonnull final FlowExecutionResult result, @Nullable final String format)
-            throws MessageDecodingException {
+    @Nonnull private AuthnRequest validateOutputMessage(@Nonnull final FlowExecutionResult result,
+            @Nullable final String format) throws MessageDecodingException {
         final ProfileRequestContext prc = retrieveProfileRequestContext(result);
         assert prc != null;
         final AgentRequestContext arc = prc.ensureSubcontext(AgentRequestContext.class);
@@ -596,8 +564,7 @@ public class SAML2SessionInitiatorFlowTest extends AbstractSPFlowTest {
         final byte[] redirect = http.getmember(RemotedHttpServletResponse.REDIRECT).unsafe_string();
         if (redirect != null) {
             final String redirectURL = new String(redirect, StandardCharsets.UTF_8);
-            final SAMLObject saml = decodeRedirect(redirectURL,
-                    input != null ? input.getmember(SPConstants.STATE).string() : null);
+            final SAMLObject saml = decodeRedirect(redirectURL);
             assert saml instanceof AuthnRequest;
             authnRequest = (AuthnRequest) saml;
             Assert.assertTrue(redirectURL.startsWith(authnRequest.getDestination()));
@@ -608,8 +575,6 @@ public class SAML2SessionInitiatorFlowTest extends AbstractSPFlowTest {
             final Object saml = prc.ensureOutboundMessageContext().ensureMessage();
             assert saml instanceof AuthnRequest;
             authnRequest = (AuthnRequest) saml;
-            Assert.assertEquals(SAMLBindingSupport.getRelayState(prc.ensureOutboundMessageContext()),
-                    input != null ? input.getmember(SPConstants.STATE).string() : null);
         }
         
         assert authnRequest != null;
@@ -625,10 +590,12 @@ public class SAML2SessionInitiatorFlowTest extends AbstractSPFlowTest {
                 if ("Set-Cookie".equals(header.name())) {
                     final String cookie = header.string();
                     assert cookie != null;
-                    if (cookie.startsWith("__Host-" + IssueCorrelationCookie.DEFAULT_COOKIE_PREFIX)) {
-                        Assert.assertEquals(cookie,
-                                "__Host-shibsp_req_" + input.getmember(SPConstants.STATE).string() + '=' + authnRequest.getID()
-                                    + "; HttpOnly; Path=/; SameSite=None; Secure");
+                    // TODO: Ideally we would extract the cookie value from the header and be able to
+                    // test against a base64'd JSON string, but that's a fair bit of work.
+                    if (cookie.startsWith("__Host-" + "shibsp_state_" + input.getmember(SPConstants.APPLICATION).string() + '_')) {
+                        Assert.assertTrue(
+                                cookie.startsWith("__Host-shibsp_state_" + input.getmember(SPConstants.APPLICATION).string() + '_'
+                                        + SAMLBindingSupport.getRelayState(prc.ensureOutboundMessageContext()) + '='));
                         foundCorrelationCookie = true;
                     }
                 }
@@ -649,12 +616,11 @@ public class SAML2SessionInitiatorFlowTest extends AbstractSPFlowTest {
      * Decodes a SAML message encoded via HTTP-Redirect binding.
      * 
      * @param url the encoded redirect
-     * @param relayState RelayState to check for
      * 
      * @return decoded message
      * @throws MessageDecodingException 
      */
-    @Nonnull protected SAMLObject decodeRedirect(@Nullable final String url, @Nullable final String relayState)
+    @Nonnull protected SAMLObject decodeRedirect(@Nullable final String url)
             throws MessageDecodingException {
         final MockHttpServletRequest mock = new MockHttpServletRequest("GET", url);
         final int index = url != null ? url.indexOf('?') : -1;
@@ -685,7 +651,6 @@ public class SAML2SessionInitiatorFlowTest extends AbstractSPFlowTest {
         decoder.destroy();
         
         if (mc != null && mc.getMessage() instanceof SAMLObject saml) {
-            Assert.assertEquals(SAMLBindingSupport.getRelayState(mc), relayState);
             return saml;
         }
         throw new MessageDecodingException("No message, or incorrect type.");
diff --git a/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/TestSPSAMLEnvironmentApplicationContextInitializer.java b/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/TestSPSAMLEnvironmentApplicationContextInitializer.java
index 5c719ef..2c54daf 100644
--- a/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/TestSPSAMLEnvironmentApplicationContextInitializer.java
+++ b/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/TestSPSAMLEnvironmentApplicationContextInitializer.java
@@ -32,6 +32,7 @@ public class TestSPSAMLEnvironmentApplicationContextInitializer extends TestSPEn
         super.addProperties(mock);
         mock.setProperty("sp.service.agents.resources", "test.sp.saml.AgentResolverResources");
         mock.setProperty("sp.agent.authn.method", "basic");
+        mock.setProperty("sp.stateToken.sealed", "false");
         mock.setProperty("idp.additionalProperties",
                 "/conf/ldap.properties, /conf/saml-nameid.properties, /conf/services.properties, /conf/admin/admin.properties, /conf/authn/authn.properties, /conf/c14n/subject-c14n.properties, /credentials/secrets.properties, /conf/sp/sp.properties, /conf/sp/saml.properties");
     }
diff --git a/sp-saml-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/sp/saml.properties b/sp-saml-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/sp/saml.properties
new file mode 100644
index 0000000..c52a348
--- /dev/null
+++ b/sp-saml-conf-impl/src/test/resources/net/shibboleth/idp/module/conf/sp/saml.properties
@@ -0,0 +1,72 @@
+# SAML-specific SP settings
+
+# Settings for SP public/private signing and encryption key(s)
+# During decryption key rollover, point the ".2" properties at a second
+# keypair, uncomment in credentials.xml, then publish it in your metadata.
+sp.saml.signing.key = %{idp.home}/credentials/sp/sp-signing.key
+sp.saml.signing.cert = %{idp.home}/credentials/sp/sp-signing.crt
+sp.saml.encryption.key = %{idp.home}/credentials/sp/sp-encryption.key
+sp.saml.encryption.cert = %{idp.home}/credentials/sp/sp-encryption.crt
+#sp.saml.encryption.key.2 = %{idp.home}/credentials/sp/sp-encryption-old.key
+#sp.saml.encryption.cert.2 = %{idp.home}/credentials/sp/sp-encryption-old.crt
+
+# Global profile defaults
+#sp.saml.encryption.optional = true
+# Turn off to allow SubjectConfirmationData/@Recipient to be absent
+#sp.saml.requireRecipient = true
+# Turn off to allow SubjectConfirmationData/@NotOnOrAfter to be absent
+#sp.saml.requireNotOnOrAfter = true
+# Turn off to disallow unsolicited SSO responses
+#sp.saml.allowUnsolicited = true
+# Turn off to disable address check during assertion validation
+#sp.saml.checkAddress = true
+# Turn off to disable message correlation checking
+#sp.saml.checkInResponseTo = true
+# Set to non-zero duration to limit time since authentication
+#sp.saml.maxTimeSinceAuthn = 0
+# Turn off to disable Asynchronous logout extension
+#sp.saml.logout.asynchronous = true
+
+# Default security configuration for SAML
+#sp.saml.security.config = shibboleth.sp.DefaultXMLSecurityConfiguration
+
+# To downgrade to SHA-1, set to shibboleth.sp.SigningConfiguration.SHA1
+#sp.saml.signing.config = shibboleth.sp.SigningConfiguration.SHA256
+
+# To upgrade to AES-GCM, set to shibboleth.sp.EncryptionConfiguration.GCM
+#sp.saml.encryption.config = shibboleth.sp.EncryptionConfiguration.CBC
+
+# Configures trust evaluation of keys used by services at runtime
+#sp.saml.trust.signatures = shibboleth.sp.ExplicitKeySignatureTrustEngine
+# Other options:
+#   shibboleth.sp.ChainingSignatureTrustEngine, shibboleth.sp.PKIXSignatureTrustEngine
+#sp.saml.trust.certificates = shibboleth.sp.ExplicitKeyX509TrustEngine
+# Other options:
+#   shibboleth.sp.ChainingX509TrustEngine, shibboleth.sp.PKIXX509TrustEngine
+
+# Set true to accept any decided attributes without a filtering rule
+sp.saml.acceptUnfilteredAttributes = false
+
+# "Standard" attribute extraction from SAML response/assertion
+sp.saml.extractStandardAttributes = false
+# Legacy names defaulted into agents
+#sp.saml.issuerAttributeId = Shib-Identity-Provider
+#sp.saml.authnInstantAttributeId = Shib-Authentication-Instant
+#sp.saml.authnContextClassRefAttributeId = Shib-AuthnContext-Class
+#sp.saml.authnContextDeclRefAttributeId = Shib-AuthnContext-Decl
+#sp.saml.sessionIndexAttributeId = Shib-Session-Index
+# Additonal extraction points available
+#sp.saml.consentAttributeId =
+#sp.saml.authorityAttributeId =
+#sp.saml.notBeforeAttributeId =
+#sp.saml.notOnOrAfterAttributeId =
+#sp.saml.sessionNotOnOrAfterAttributeId =
+#sp.saml.addressAttributeId =
+#sp.saml.dnsNameAttributeId =
+
+# Configures use of the Attribute Resolver for enrichment
+#sp.saml.resolveAttributes = false
+
+# Each protocol plugin will contain an order priority controlling
+# relative order of use when handling requests, lower is "earlier".
+#sp.saml.relativeOrder = 1

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


More information about the commits mailing list