[java-plugin-shibd-saml] branch main updated: Add SOAP header checks for ECP tests.
Codeberg
noreply at shibboleth.net
Mon Aug 10 15:23:59 UTC 2026
This is an automated email from the git hooks/post-receive script.
codeberg pushed a commit to branch main
in repository java-plugin-shibd-saml.
View the commit online:
https://codeberg.org/Shibboleth/java-plugin-shibd-saml/commit/be4444b8fab79300d8f66f3d4cceb419f37dd7be
The following commit(s) were added to refs/heads/main by this push:
new be4444b Add SOAP header checks for ECP tests.
be4444b is described below
commit be4444b8fab79300d8f66f3d4cceb419f37dd7be
Author: Scott Cantor <scott at restingparrotsoftware.com>
AuthorDate: Mon Aug 10 11:23:45 2026 -0400
Add SOAP header checks for ECP tests.
---
.../flows/saml2/ECPSessionInitiatorFlowTest.java | 76 ++++++++++++++++++++--
.../binding/impl/AddECPRequestHeaderHandler.java | 6 +-
2 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/ECPSessionInitiatorFlowTest.java b/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/ECPSessionInitiatorFlowTest.java
index 4b7074f..b3be667 100644
--- a/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/ECPSessionInitiatorFlowTest.java
+++ b/sp-saml-conf-impl/src/test/java/net/shibboleth/sp/saml/flows/saml2/ECPSessionInitiatorFlowTest.java
@@ -22,6 +22,7 @@ import java.time.Instant;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.io.UnmarshallingException;
import org.opensaml.core.xml.util.XMLObjectSupport;
import org.opensaml.profile.action.EventIds;
@@ -31,7 +32,12 @@ import org.opensaml.saml.common.xml.SAMLConstants;
import org.opensaml.saml.saml2.core.AuthnRequest;
import org.opensaml.saml.saml2.core.Issuer;
import org.opensaml.saml.saml2.core.NameIDPolicy;
+import org.opensaml.saml.saml2.ecp.RelayState;
+import org.opensaml.saml.saml2.ecp.Request;
+import org.opensaml.soap.soap11.ActorBearing;
+import org.opensaml.soap.soap11.Body;
import org.opensaml.soap.soap11.Envelope;
+import org.opensaml.soap.soap11.Header;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.webflow.executor.FlowExecutionResult;
@@ -41,7 +47,7 @@ import org.testng.annotations.Test;
import net.shibboleth.idp.profile.IdPEventIds;
import net.shibboleth.idp.spring.IdPPropertiesApplicationContextInitializer;
import net.shibboleth.idp.test.PreferFileSystemApplicationContextInitializer;
-import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.ConstraintViolationException;
import net.shibboleth.shared.xml.XMLParserException;
import net.shibboleth.sp.context.AgentRequestContext;
import net.shibboleth.sp.ddf.DDF;
@@ -53,7 +59,7 @@ import net.shibboleth.sp.profile.SPConstants;
import net.shibboleth.sp.saml.saml2.profile.SAML2InitiatorConstants;
/**
- * Unit test for the SP session-initiator flow.
+ * Unit test for the ECP session-initiator flow.
*/
@ContextConfiguration(
locations = {
@@ -270,7 +276,7 @@ public class ECPSessionInitiatorFlowTest extends AbstractSPFlowTest {
final byte[] body = http.getmember(RemotedHttpServletResponse.RESPONSE).getmember(RemotedHttpServletResponse.DATA).unsafe_string();
assert body != null;
final Envelope env = decodeSOAPEnvelope(body);
- final AuthnRequest authnRequest = (AuthnRequest) Constraint.isNotNull(env.getBody(), "Body was null").getUnknownXMLObjects().get(0);
+ final AuthnRequest authnRequest = validateSOAPEnvelope(env, SAMLBindingSupport.getRelayState(prc.ensureOutboundMessageContext()));
Assert.assertNotNull(authnRequest.getID());
Assert.assertEquals(authnRequest.getProtocolBinding(), SAMLConstants.SAML2_PAOS_BINDING_URI);
@@ -316,7 +322,7 @@ public class ECPSessionInitiatorFlowTest extends AbstractSPFlowTest {
* @throws IOException
* @throws UnmarshallingException
*/
- @Nonnull protected Envelope decodeSOAPEnvelope(@Nonnull final byte[] body)
+ @Nonnull private Envelope decodeSOAPEnvelope(@Nonnull final byte[] body)
throws IOException, UnmarshallingException, XMLParserException {
@@ -324,5 +330,67 @@ public class ECPSessionInitiatorFlowTest extends AbstractSPFlowTest {
return (Envelope) XMLObjectSupport.unmarshallFromInputStream(parserPool, in);
}
}
+
+ /**
+ * Validate SOAP content.
+ *
+ * @param env envelope
+ * @param relayState relay state from binding if any
+ *
+ * @return the body payload
+ */
+ @Nonnull private AuthnRequest validateSOAPEnvelope(@Nonnull final Envelope env, @Nullable final String relayState) {
+
+ final AuthnRequest request;
+ final Body body = env.getBody();
+ assert body != null;
+ if (body.getUnknownXMLObjects().get(0) instanceof AuthnRequest req) {
+ request = req;
+ } else {
+ throw new ConstraintViolationException("Body did not contain AuthnRequest");
+ }
+
+ final Header header = env.getHeader();
+ assert header != null;
+
+ Assert.assertEquals(header.getUnknownXMLObjects().size(), 3);
+
+ for (final XMLObject block : header.getUnknownXMLObjects()) {
+ if (block instanceof net.shibboleth.sp.liberty.paos.Request paos) {
+
+ Assert.assertEquals(paos.isSOAP11MustUnderstand(), true);
+ Assert.assertEquals(paos.getSOAP11Actor(), ActorBearing.SOAP11_ACTOR_NEXT);
+ Assert.assertEquals(paos.getMessageID(), request.getID());
+ Assert.assertEquals(paos.getResponseConsumerURL(), request.getAssertionConsumerServiceURL());
+ Assert.assertEquals(paos.getService(), SAMLConstants.SAML20ECP_NS);
+
+ } else if (block instanceof Request ecp) {
+
+ final Issuer reqIssuer = request.getIssuer();
+ final Issuer ecpIssuer = ecp.getIssuer();
+ assert reqIssuer != null && ecpIssuer != null;
+ Assert.assertEquals(reqIssuer.getValue(), ecpIssuer.getValue());
+
+ final Boolean reqPassive = request.isPassive();
+ final Boolean ecpPassive = ecp.isPassive();
+ Assert.assertEquals(ecpPassive, reqPassive != null && reqPassive);
+
+ Assert.assertNull(ecp.getProviderName());
+ Assert.assertNull(ecp.getIDPList());
+ Assert.assertEquals(ecp.isSOAP11MustUnderstand(), true);
+ Assert.assertEquals(ecp.getSOAP11Actor(), ActorBearing.SOAP11_ACTOR_NEXT);
+
+ } else if (block instanceof RelayState state) {
+
+ Assert.assertEquals(state.getValue(), relayState);
+ Assert.assertEquals(state.isSOAP11MustUnderstand(), true);
+ Assert.assertEquals(state.getSOAP11Actor(), ActorBearing.SOAP11_ACTOR_NEXT);
+
+ }
+ }
+
+ return req;
+
+ }
}
\ No newline at end of file
diff --git a/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/binding/impl/AddECPRequestHeaderHandler.java b/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/binding/impl/AddECPRequestHeaderHandler.java
index b2e2644..7fb890f 100644
--- a/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/binding/impl/AddECPRequestHeaderHandler.java
+++ b/sp-saml-impl/src/main/java/net/shibboleth/sp/saml/saml2/binding/impl/AddECPRequestHeaderHandler.java
@@ -82,10 +82,10 @@ public class AddECPRequestHeaderHandler extends AbstractMessageHandler {
final Request header = requestBuilder.buildObject(Request.DEFAULT_ELEMENT_NAME);
// IsPassive in this header block defaults to true if absent (no idea why we did that).
+ // OpenSAML also has the wrong default on this, so at least for test sanity, I'm setting
+ // it either way to the expected value.
final Boolean passive = authnRequest.isPassive();
- if (passive == null || !passive) {
- header.setPassive(false);
- }
+ header.setPassive(passive != null && passive);
final Issuer issuer = authnRequest.getIssuer();
if (issuer != null) {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list