[java-opensaml] branch main updated: OSJ-430 - Make InResponseTo validation optional
Scott Cantor
cantor.2 at osu.edu
Thu Apr 3 19:49:23 UTC 2025
This is an automated email from the git hooks/post-receive script.
scantor pushed a commit to branch main
in repository java-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=276cb1ea73bb01fe790cffbee6814d8f6c394ee7
The following commit(s) were added to refs/heads/main by this push:
new 276cb1ea7 OSJ-430 - Make InResponseTo validation optional
276cb1ea7 is described below
commit 276cb1ea73bb01fe790cffbee6814d8f6c394ee7
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu Apr 3 15:49:20 2025 -0400
OSJ-430 - Make InResponseTo validation optional
https://shibboleth.atlassian.net/browse/OSJ-430
Add "ignore InResponseTo" condition/parameter to assertion validator.
---
.../SAML2AssertionValidationParameters.java | 15 ++++-
.../impl/AbstractSubjectConfirmationValidator.java | 39 ++++++++++---
.../DefaultAssertionValidationContextBuilder.java | 45 +++++++++++++--
.../AbstractSubjectConfirmationValidatorTest.java | 66 +++++++++++++---------
4 files changed, 122 insertions(+), 43 deletions(-)
diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/SAML2AssertionValidationParameters.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/SAML2AssertionValidationParameters.java
index 6d163d8f7..82249c7ea 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/SAML2AssertionValidationParameters.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/SAML2AssertionValidationParameters.java
@@ -145,14 +145,23 @@ public final class SAML2AssertionValidationParameters {
/**
* Carries a {@link java.lang.Boolean} flag which indicates whether
- * {@link org.opensaml.saml.saml2.core.SubjectConfirmationData} InResponseTo is required.
+ * {@link org.opensaml.saml.saml2.core.SubjectConfirmationData#getInResponseTo()} should be ignored.
+ *
+ * @since 5.2.0
+ */
+ @Nonnull @NotEmpty public static final String SC_IN_RESPONSE_TO_IGNORED =
+ STD_PREFIX + SC_INFIX + ".InResponseToIgnored";
+
+ /**
+ * Carries a {@link java.lang.Boolean} flag which indicates whether
+ * {@link org.opensaml.saml.saml2.core.SubjectConfirmationData#getInResponseTo()} is required to be non-null.
*/
@Nonnull @NotEmpty public static final String SC_IN_RESPONSE_TO_REQUIRED =
STD_PREFIX + SC_INFIX + ".InResponseToRequired";
/**
- * Carries a {@link java.lang.String} whose value is the acceptable
- * {@link org.opensaml.saml.saml2.core.SubjectConfirmationData} InResponseTo.
+ * Carries a {@link java.lang.String} whose value is the acceptable point of comparison against
+ * {@link org.opensaml.saml.saml2.core.SubjectConfirmationData#getInResponseTo()}.
*/
@Nonnull @NotEmpty public static final String SC_VALID_IN_RESPONSE_TO =
STD_PREFIX + SC_INFIX + ".ValidInResponseTo";
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AbstractSubjectConfirmationValidator.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AbstractSubjectConfirmationValidator.java
index f84edb8c7..4152b4bb0 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AbstractSubjectConfirmationValidator.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AbstractSubjectConfirmationValidator.java
@@ -107,6 +107,7 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
throws AssertionValidationException {
final boolean addressRequired = isAddressRequired(context);
+ final boolean inResponseToIgnored = isInResponseToIgnored(context);
final boolean inResponseToRequired = isInResponseToRequired(context);
final boolean recipientRequired = isRecipientRequired(context);
final boolean notOnOrAfterRequired = isNotOnOrAfterRequired(context);
@@ -133,14 +134,16 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
if (result != ValidationResult.VALID) {
return result;
}
-
- result = validateInResponseTo(confirmationData, assertion, context, inResponseToRequired);
- if (result != ValidationResult.VALID) {
- return result;
+
+ if (!inResponseToIgnored) {
+ result = validateInResponseTo(confirmationData, assertion, context, inResponseToRequired);
+ if (result != ValidationResult.VALID) {
+ return result;
+ }
}
} else {
- if (inResponseToRequired || recipientRequired || notOnOrAfterRequired || notBeforeRequired
- || addressRequired) {
+ if ((!inResponseToIgnored && inResponseToRequired) || recipientRequired || notOnOrAfterRequired
+ || notBeforeRequired || addressRequired) {
context.getValidationFailureMessages().add(
"SubjectConfirmationData was null and one or more data elements were required");
return ValidationResult.INVALID;
@@ -211,6 +214,23 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
return flag != null ? flag : false;
}
+ /**
+ * Determine whether InResponseTo is ignored.
+ *
+ * @param context current validation context
+ *
+ * @return true if ignored, false if not
+ *
+ * @since 5.2.0
+ */
+ protected boolean isInResponseToIgnored(final ValidationContext context) {
+ final Boolean flag = ObjectSupport.firstNonNull(
+ (Boolean) context.getStaticParameters().get(
+ SAML2AssertionValidationParameters.SC_IN_RESPONSE_TO_IGNORED),
+ Boolean.FALSE);
+ return flag != null ? flag : false;
+ }
+
/**
* Determine whether InResponseTo is required.
*
@@ -227,7 +247,7 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
}
/**
- * Validates the <code>InResponseTo</code> condition of the {@link SubjectConfirmationData}, if any is present.
+ * Validates the <code>InResponseTo</code> value of the {@link SubjectConfirmationData}, if any is present.
*
* @param confirmationData confirmation data being validated
* @param assertion assertion bearing the confirmation method
@@ -265,8 +285,9 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
return ValidationResult.INDETERMINATE;
}
if (validInResponseTo == null) {
- context.getValidationFailureMessages().add("Valid InResponseTo was not available from the validation context, "
- + "unable to evaluate SubjectConfirmationData at InResponseTo");
+ context.getValidationFailureMessages().add(
+ "Valid InResponseTo was not available from the validation context, "
+ + "unable to evaluate SubjectConfirmationData at InResponseTo");
return ValidationResult.INDETERMINATE;
}
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/profile/impl/DefaultAssertionValidationContextBuilder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/profile/impl/DefaultAssertionValidationContextBuilder.java
index f0ca65130..4cc0a6703 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/profile/impl/DefaultAssertionValidationContextBuilder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/profile/impl/DefaultAssertionValidationContextBuilder.java
@@ -124,7 +124,10 @@ public class DefaultAssertionValidationContextBuilder
/** Function for determining the valid InResponseTo value. */
@Nullable private Function<ProfileRequestContext, String> inResponseTo;
-
+
+ /** Predicate for determining whether an Assertion SubjectConfirmationData InResponseTo is ignored. */
+ @Nonnull private Predicate<ProfileRequestContext> inResponseToIgnored;
+
/** Predicate for determining whether an Assertion SubjectConfirmationData InResponseTo is required. */
@Nonnull private Predicate<ProfileRequestContext> inResponseToRequired;
@@ -154,6 +157,7 @@ public class DefaultAssertionValidationContextBuilder
includeSelfEntityIDAsRecipient = PredicateSupport.alwaysFalse();
checkAddress = PredicateSupport.alwaysTrue();
inResponseTo = new DefaultValidInResponseToLookupFunction();
+ inResponseToIgnored = PredicateSupport.alwaysFalse();
inResponseToRequired = PredicateSupport.alwaysFalse();
recipientRequired = PredicateSupport.alwaysFalse();
notOnOrAfterRequired = PredicateSupport.alwaysFalse();
@@ -163,8 +167,9 @@ public class DefaultAssertionValidationContextBuilder
validIssuers = new DefaultValidIssuersLookupFunction();
requireEntityIssuer = PredicateSupport.alwaysFalse();
- securityParametersLookupStrategy = new ChildContextLookup<>(SecurityParametersContext.class)
- .compose(new InboundMessageContextLookup());
+ securityParametersLookupStrategy =
+ new ChildContextLookup<>(SecurityParametersContext.class).compose(
+ new InboundMessageContextLookup());
}
/**
@@ -381,6 +386,36 @@ public class DefaultAssertionValidationContextBuilder
inResponseToRequired = Constraint.isNotNull(predicate, "InResponseTo required predicate was null");
}
+ /**
+ * Get the predicate which determines whether an Assertion SubjectConfirmationData InResponseTo is ignored.
+ *
+ * <p>
+ * Defaults to an always false predicate;
+ * </p>
+ *
+ * @return the predicate
+ *
+ * @since 5.2.0
+ */
+ @Nonnull public Predicate<ProfileRequestContext> getInResponseToIgnored() {
+ return inResponseToIgnored;
+ }
+
+ /**
+ * Set the predicate which determines whether an Assertion SubjectConfirmationData InResponseTo is ignored.
+ *
+ * <p>
+ * Defaults to an always false predicate.
+ * </p>
+ *
+ * @param predicate the predicate, must be non-null
+ *
+ * @since 5.2.0
+ */
+ public void setInResponseToIgnored(@Nonnull final Predicate<ProfileRequestContext> predicate) {
+ inResponseToIgnored = Constraint.isNotNull(predicate, "InResponseTo ignored predicate was null");
+ }
+
/**
* Get the predicate which determines whether an Assertion SubjectConfirmationData Recipient is required.
*
@@ -774,7 +809,9 @@ public class DefaultAssertionValidationContextBuilder
Boolean.valueOf(getAddressRequired().test(input.getProfileRequestContext())));
staticParams.put(SAML2AssertionValidationParameters.SC_VALID_ADDRESSES, validAddresses);
staticParams.put(SAML2AssertionValidationParameters.SC_CHECK_ADDRESS, checkAddressEnabled);
-
+
+ staticParams.put(SAML2AssertionValidationParameters.SC_IN_RESPONSE_TO_IGNORED,
+ Boolean.valueOf(getInResponseToIgnored().test(input.getProfileRequestContext())));
staticParams.put(SAML2AssertionValidationParameters.SC_IN_RESPONSE_TO_REQUIRED,
Boolean.valueOf(getInResponseToRequired().test(input.getProfileRequestContext())));
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/impl/AbstractSubjectConfirmationValidatorTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/impl/AbstractSubjectConfirmationValidatorTest.java
index 09e41d9ea..aaf3c15be 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/impl/AbstractSubjectConfirmationValidatorTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/impl/AbstractSubjectConfirmationValidatorTest.java
@@ -53,7 +53,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.VALID);
+ ValidationResult.VALID);
}
@Test
@@ -63,7 +63,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.VALID);
+ ValidationResult.VALID);
}
@Test
@@ -73,7 +73,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Test
@@ -97,7 +97,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INDETERMINATE);
+ ValidationResult.INDETERMINATE);
}
@Test
@@ -108,7 +108,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INDETERMINATE);
+ ValidationResult.INDETERMINATE);
}
@Test
@@ -118,7 +118,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.VALID);
+ ValidationResult.VALID);
}
@Test
@@ -130,7 +130,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Test
@@ -142,7 +142,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Test
@@ -152,7 +152,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Test
@@ -164,7 +164,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INDETERMINATE);
+ ValidationResult.INDETERMINATE);
}
@Test
@@ -175,7 +175,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INDETERMINATE);
+ ValidationResult.INDETERMINATE);
}
@Test
@@ -185,7 +185,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.VALID);
+ ValidationResult.VALID);
}
@Test
@@ -221,7 +221,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Test
@@ -231,7 +231,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.VALID);
+ ValidationResult.VALID);
}
@Test
@@ -243,7 +243,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Test
@@ -255,7 +255,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Test
@@ -267,7 +267,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Test
@@ -277,7 +277,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.VALID);
+ ValidationResult.VALID);
}
@Test
@@ -289,7 +289,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Test
@@ -301,7 +301,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Test
@@ -311,9 +311,21 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
-
+
+ @Test
+ public void testInvalidInResponseToButIgnored() throws AssertionValidationException {
+ getSubjectConfirmationData().setInResponseTo("invalid");
+
+ Map<String,Object> staticParams = buildBasicStaticParameters();
+ staticParams.put(SAML2AssertionValidationParameters.SC_IN_RESPONSE_TO_IGNORED, Boolean.valueOf(true));
+ ValidationContext validationContext = new ValidationContext(staticParams);
+
+ Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
+ ValidationResult.VALID);
+ }
+
@Test
public void testInvalidInResponseToParamType() throws AssertionValidationException {
Map<String,Object> staticParams = buildBasicStaticParameters();
@@ -323,7 +335,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INDETERMINATE);
+ ValidationResult.INDETERMINATE);
}
@Test
@@ -334,7 +346,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INDETERMINATE);
+ ValidationResult.INDETERMINATE);
}
@Test
@@ -344,7 +356,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(buildBasicStaticParameters());
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.VALID);
+ ValidationResult.VALID);
}
@Test
@@ -356,7 +368,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Test
@@ -368,7 +380,7 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
ValidationContext validationContext = new ValidationContext(staticParams);
Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
- ValidationResult.INVALID);
+ ValidationResult.INVALID);
}
@Nonnull private SubjectConfirmationData getSubjectConfirmationData() {
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list