[java-opensaml] 05/11: Support additional required checks over SubjectConfirmationData.
Brent Putman
putmanb at georgetown.edu
Thu Jan 30 02:17:30 EST 2020
This is an automated email from the git hooks/post-receive script.
putmanb pushed a commit to branch master
in repository java-opensaml.
View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=44ac147db7c51f025ccd22a64ab1bec37c5d0d35
commit 44ac147db7c51f025ccd22a64ab1bec37c5d0d35
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Wed Jan 29 21:07:22 2020 -0500
Support additional required checks over SubjectConfirmationData.
---
.../SAML2AssertionValidationParameters.java | 24 +++
.../impl/AbstractSubjectConfirmationValidator.java | 168 +++++++++++++++++--
.../DefaultAssertionValidationContextBuilder.java | 177 ++++++++++++++++++---
.../AbstractSubjectConfirmationValidatorTest.java | 96 +++++++++++
4 files changed, 426 insertions(+), 39 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 6e0b0b4..7166303 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
@@ -73,6 +73,24 @@ public final class SAML2AssertionValidationParameters {
public static final String SIGNATURE_VALIDATION_PREVALIDATOR = STD_PREFIX + ".SignatureValidationPrevalidator";
/**
+ * Carries a {@link java.lang.Boolean} flag which indicates whether
+ * {@link org.opensaml.saml.saml2.core.SubjectConfirmationData} NotBefore is required.
+ */
+ public static final String SC_NOT_BEFORE_REQUIRED = STD_PREFIX + SC_INFIX + ".NotBeforeRequired";
+
+ /**
+ * Carries a {@link java.lang.Boolean} flag which indicates whether
+ * {@link org.opensaml.saml.saml2.core.SubjectConfirmationData} NotOnOrAfter is required.
+ */
+ public static final String SC_NOT_ON_OR_AFTER_REQUIRED = STD_PREFIX + SC_INFIX + ".NoOnOrAfterRequired";
+
+ /**
+ * Carries a {@link java.lang.Boolean} flag which indicates whether
+ * {@link org.opensaml.saml.saml2.core.SubjectConfirmationData} Recipient is required.
+ */
+ public static final String SC_RECIPIENT_REQUIRED = STD_PREFIX + SC_INFIX + ".RecipientRequired";
+
+ /**
* Carries a {@link java.util.Set}<code><</code>{@link java.lang.String}<code>></code>
* whose values are the acceptable
* {@link org.opensaml.saml.saml2.core.SubjectConfirmationData} recipients.
@@ -81,6 +99,12 @@ public final class SAML2AssertionValidationParameters {
/**
* Carries a {@link java.lang.Boolean} flag which indicates whether the
+ * {@link org.opensaml.saml.saml2.core.SubjectConfirmationData} Address is required.
+ */
+ public static final String SC_ADDRESS_REQUIRED = STD_PREFIX + SC_INFIX + ".AddressRequired";
+
+ /**
+ * Carries a {@link java.lang.Boolean} flag which indicates whether the
* {@link org.opensaml.saml.saml2.core.SubjectConfirmationData} address should be checked.
*/
public static final String SC_CHECK_ADDRESS = STD_PREFIX + SC_INFIX + ".CheckAddress";
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 a4203b6..3c4a069 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
@@ -51,6 +51,10 @@ import net.shibboleth.utilities.java.support.primitive.StringSupport;
* </p>
* <ul>
* <li>
+ * {@link SAML2AssertionValidationParameters#SC_ADDRESS_REQUIRED}:
+ * Optional.
+ * </li>
+ * <li>
* {@link SAML2AssertionValidationParameters#SC_CHECK_ADDRESS}:
* Optional.
* </li>
@@ -60,13 +64,29 @@ import net.shibboleth.utilities.java.support.primitive.StringSupport;
* otherwise optional.
* </li>
* <li>
+ * {@link SAML2AssertionValidationParameters#SC_RECIPIENT_REQUIRED}:
+ * Optional.
+ * </li>
+ * <li>
* {@link SAML2AssertionValidationParameters#SC_VALID_RECIPIENTS}:
* Required.
* </li>
* <li>
+ * {@link SAML2AssertionValidationParameters#SC_IN_RESPONSE_TO_REQUIRED}:
+ * Optional.
+ * </li>
+ * <li>
* {@link SAML2AssertionValidationParameters#SC_VALID_IN_RESPONSE_TO}:
* Required.
* </li>
+ * <li>
+ * {@link SAML2AssertionValidationParameters#SC_NOT_BEFORE_REQUIRED}:
+ * Optional.
+ * </li>
+ * <li>
+ * {@link SAML2AssertionValidationParameters#SC_NOT_ON_OR_AFTER_REQUIRED}:
+ * Optional.
+ * </li>
* </ul>
*
* <p>
@@ -87,29 +107,34 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
}
/** {@inheritDoc} */
+ // Checkstyle: CyclomaticComplexity OFF
@Nonnull public ValidationResult validate(@Nonnull final SubjectConfirmation confirmation,
@Nonnull final Assertion assertion, @Nonnull final ValidationContext context)
throws AssertionValidationException {
+ final boolean addressRequired = isAddressRequired(context);
final boolean inResponseToRequired = isInResponseToRequired(context);
+ final boolean recipientRequired = isRecipientRequired(context);
+ final boolean notOnOrAfterRequired = isNotOnOrAfterRequired(context);
+ final boolean notBeforeRequired = isNotBeforeRequired(context);
if (confirmation.getSubjectConfirmationData() != null) {
- ValidationResult result = validateNotBefore(confirmation, assertion, context);
+ ValidationResult result = validateNotBefore(confirmation, assertion, context, notBeforeRequired);
if (result != ValidationResult.VALID) {
return result;
}
- result = validateNotOnOrAfter(confirmation, assertion, context);
+ result = validateNotOnOrAfter(confirmation, assertion, context, notOnOrAfterRequired);
if (result != ValidationResult.VALID) {
return result;
}
- result = validateRecipient(confirmation, assertion, context);
+ result = validateRecipient(confirmation, assertion, context, recipientRequired);
if (result != ValidationResult.VALID) {
return result;
}
- result = validateAddress(confirmation, assertion, context);
+ result = validateAddress(confirmation, assertion, context, addressRequired);
if (result != ValidationResult.VALID) {
return result;
}
@@ -119,14 +144,82 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
return result;
}
} else {
- if (inResponseToRequired) {
+ if (inResponseToRequired || recipientRequired || notOnOrAfterRequired || notBeforeRequired
+ || addressRequired) {
+ log.warn("SubjectConfirmationData was null, and one of more data elements were required");
+ context.setValidationFailureMessage(
+ "SubjectConfirmationData was null and one or more data elements were required");
return ValidationResult.INVALID;
}
}
return doValidate(confirmation, assertion, context);
}
+ // Checkstyle: CyclomaticComplexity ON
+
+ /**
+ * Determine whether Address is required.
+ *
+ * @param context current validation context
+ *
+ * @return true if required, false if not
+ */
+ protected boolean isAddressRequired(final ValidationContext context) {
+ return ObjectSupport.firstNonNull(
+ (Boolean) context.getStaticParameters().get(
+ SAML2AssertionValidationParameters.SC_ADDRESS_REQUIRED),
+ Boolean.FALSE);
+ }
+
+ /**
+ * Determine whether Recipient is required.
+ *
+ * @param context current validation context
+ *
+ * @return true if required, false if not
+ */
+ protected boolean isRecipientRequired(final ValidationContext context) {
+ return ObjectSupport.firstNonNull(
+ (Boolean) context.getStaticParameters().get(
+ SAML2AssertionValidationParameters.SC_RECIPIENT_REQUIRED),
+ Boolean.FALSE);
+ }
+
+ /**
+ * Determine whether NotBefore is required.
+ *
+ * @param context current validation context
+ *
+ * @return true if required, false if not
+ */
+ protected boolean isNotBeforeRequired(final ValidationContext context) {
+ return ObjectSupport.firstNonNull(
+ (Boolean) context.getStaticParameters().get(
+ SAML2AssertionValidationParameters.SC_NOT_BEFORE_REQUIRED),
+ Boolean.FALSE);
+ }
+
+ /**
+ * Determine whether NotOnOrAfter is required.
+ *
+ * @param context current validation context
+ *
+ * @return true if required, false if not
+ */
+ protected boolean isNotOnOrAfterRequired(final ValidationContext context) {
+ return ObjectSupport.firstNonNull(
+ (Boolean) context.getStaticParameters().get(
+ SAML2AssertionValidationParameters.SC_NOT_ON_OR_AFTER_REQUIRED),
+ Boolean.FALSE);
+ }
+ /**
+ * Determine whether InResponseTo is required.
+ *
+ * @param context current validation context
+ *
+ * @return true if required, false if not
+ */
protected boolean isInResponseToRequired(final ValidationContext context) {
return ObjectSupport.firstNonNull(
(Boolean) context.getStaticParameters().get(
@@ -142,7 +235,7 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
* being validated
* @param assertion assertion bearing the confirmation method
* @param context current validation context
- * @param required whether the inResponseTo value is required
+ * @param required whether the InResponseTo value is required
*
* @return the result of the validation evaluation
*
@@ -205,16 +298,28 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
* being validated
* @param assertion assertion bearing the confirmation method
* @param context current validation context
+ * @param required
*
* @return the result of the validation evaluation
*
* @throws AssertionValidationException thrown if there is a problem determining the validity of the NotBefore
*/
@Nonnull protected ValidationResult validateNotBefore(@Nonnull final SubjectConfirmation confirmation,
- @Nonnull final Assertion assertion, @Nonnull final ValidationContext context)
- throws AssertionValidationException {
- final Instant skewedNow = Instant.now().plus(SAML20AssertionValidator.getClockSkew(context));
+ @Nonnull final Assertion assertion, @Nonnull final ValidationContext context,
+ final boolean required) throws AssertionValidationException {
+
final Instant notBefore = confirmation.getSubjectConfirmationData().getNotBefore();
+ if (notBefore == null) {
+ if (required) {
+ log.warn("SubjectConfirmationData/@NotBefore was missing and was required");
+ context.setValidationFailureMessage(
+ "SubjectConfirmationData/@NotBefore was missing and was required");
+ return ValidationResult.INVALID;
+ }
+ return ValidationResult.VALID;
+ }
+
+ final Instant skewedNow = Instant.now().plus(SAML20AssertionValidator.getClockSkew(context));
log.debug("Evaluating SubjectConfirmationData NotBefore '{}' against 'skewed now' time '{}'",
notBefore, skewedNow);
@@ -236,16 +341,28 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
* being validated
* @param assertion assertion bearing the confirmation method
* @param context current validation context
+ * @param required whether the NotOnOrAfter value is required
*
* @return the result of the validation evaluation
*
* @throws AssertionValidationException thrown if there is a problem determining the validity of the NotOnOrAFter
*/
@Nonnull protected ValidationResult validateNotOnOrAfter(@Nonnull final SubjectConfirmation confirmation,
- @Nonnull final Assertion assertion, @Nonnull final ValidationContext context)
+ @Nonnull final Assertion assertion, @Nonnull final ValidationContext context, final boolean required)
throws AssertionValidationException {
- final Instant skewedNow = Instant.now().minus(SAML20AssertionValidator.getClockSkew(context));
+
final Instant notOnOrAfter = confirmation.getSubjectConfirmationData().getNotOnOrAfter();
+ if (notOnOrAfter == null) {
+ if (required) {
+ log.warn("SubjectConfirmationData/@NotOnOrAfter was missing and was required");
+ context.setValidationFailureMessage(
+ "SubjectConfirmationData/@NotOnOrAfter was missing and was required");
+ return ValidationResult.INVALID;
+ }
+ return ValidationResult.VALID;
+ }
+
+ final Instant skewedNow = Instant.now().minus(SAML20AssertionValidator.getClockSkew(context));
log.debug("Evaluating SubjectConfirmationData NotOnOrAfter '{}' against 'skewed now' time '{}'",
notOnOrAfter, skewedNow);
@@ -266,16 +383,25 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
* @param confirmation confirmation method being validated
* @param assertion assertion bearing the confirmation method
* @param context current validation context
+ * @param required whether the Recipient value is required
*
* @return the result of the validation evaluation
*
* @throws AssertionValidationException thrown if there is a problem determining the validity of the recipient
*/
@Nonnull protected ValidationResult validateRecipient(@Nonnull final SubjectConfirmation confirmation,
- @Nonnull final Assertion assertion, @Nonnull final ValidationContext context)
+ @Nonnull final Assertion assertion, @Nonnull final ValidationContext context, final boolean required)
throws AssertionValidationException {
- final String recipient = StringSupport.trimOrNull(confirmation.getSubjectConfirmationData().getRecipient());
+
+ final String recipient =
+ StringSupport.trimOrNull(confirmation.getSubjectConfirmationData().getRecipient());
if (recipient == null) {
+ if (required) {
+ log.warn("SubjectConfirmationData/@Recipient was missing and was required");
+ context.setValidationFailureMessage(
+ "SubjectConfirmationData/@Recipient was missing and was required");
+ return ValidationResult.INVALID;
+ }
return ValidationResult.VALID;
}
@@ -299,8 +425,6 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
"Unable to determine list of valid subject confirmation recipient endpoints");
return ValidationResult.INDETERMINATE;
}
-
-
if (validRecipients.contains(recipient)) {
log.debug("Matched valid recipient: {}", recipient);
@@ -311,7 +435,7 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
validRecipients);
context.setValidationFailureMessage(String.format(
- "Subject confirmation recipient for asertion '%s' did not match any valid recipients", assertion
+ "Subject confirmation recipient for assertion '%s' did not match any valid recipients", assertion
.getID()));
return ValidationResult.INVALID;
}
@@ -323,13 +447,14 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
* @param confirmation confirmation method being validated
* @param assertion assertion bearing the confirmation method
* @param context current validation context
+ * @param required whether the Address value is required
*
* @return the result of the validation evaluation
*
* @throws AssertionValidationException thrown if there is a problem determining the validity of the address
*/
@Nonnull protected ValidationResult validateAddress(@Nonnull final SubjectConfirmation confirmation,
- @Nonnull final Assertion assertion, @Nonnull final ValidationContext context)
+ @Nonnull final Assertion assertion, @Nonnull final ValidationContext context, final boolean required)
throws AssertionValidationException {
final Boolean checkAddress =
@@ -341,6 +466,15 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
}
final String address = StringSupport.trimOrNull(confirmation.getSubjectConfirmationData().getAddress());
+ if (address == null) {
+ if (required) {
+ log.warn("SubjectConfirmationData/@Address was missing and was required");
+ context.setValidationFailureMessage(
+ "SubjectConfirmationData/@Address was missing and was required");
+ return ValidationResult.INVALID;
+ }
+ return ValidationResult.VALID;
+ }
return AssertionValidationSupport.checkAddress(context, address,
SAML2AssertionValidationParameters.SC_VALID_ADDRESSES,
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 7c8c5b6..96c11be 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
@@ -98,11 +98,25 @@ public class DefaultAssertionValidationContextBuilder
/** Function for determining additional valid audience values. */
private Function<ProfileRequestContext, Set<String>> additionalAudiences;
- /** Predicate for determining whether an Assertion's InResponseTo is required. */
- private Predicate<ProfileRequestContext> inResponseToRequired;
-
/** Function for determining the valid InResponseTo value. */
private Function<ProfileRequestContext, String> inResponseTo;
+
+ /** Predicate for determining whether an Assertion SubjectConfirmationData InResponseTo is required. */
+ private Predicate<ProfileRequestContext> inResponseToRequired;
+
+ /** Predicate for determining whether an Assertion SubjectConfirmationData Recipient is required. */
+ private Predicate<ProfileRequestContext> recipientRequired;
+
+ /** Predicate for determining whether an Assertion SubjectConfirmationData NotBefore is required. */
+ private Predicate<ProfileRequestContext> notBeforeRequired;
+
+ /** Predicate for determining whether an Assertion SubjectConfirmationData NotOnOrAfter is required. */
+ private Predicate<ProfileRequestContext> notOnOrAfterRequired;
+
+ /** Predicate for determining whether an Assertion SubjectConfirmationData Address is required. */
+ private Predicate<ProfileRequestContext> addressRequired;
+
+
/** Resolver for security parameters context. */
private Function<ProfileRequestContext, SecurityParametersContext> securityParametersLookupStrategy;
@@ -114,8 +128,12 @@ public class DefaultAssertionValidationContextBuilder
signatureRequired = Predicates.alwaysTrue();
includeSelfEntityIDAsRecipient = Predicates.alwaysFalse();
checkAddress = Predicates.alwaysTrue();
- inResponseToRequired = Predicates.alwaysFalse();
inResponseTo = new DefaultValidInResponseToLookupFunction();
+ inResponseToRequired = Predicates.alwaysFalse();
+ recipientRequired = Predicates.alwaysFalse();
+ notOnOrAfterRequired = Predicates.alwaysFalse();
+ notBeforeRequired = Predicates.alwaysFalse();
+ addressRequired = Predicates.alwaysFalse();
securityParametersLookupStrategy = new ChildContextLookup<>(SecurityParametersContext.class)
.compose(new InboundMessageContextLookup());
@@ -194,7 +212,33 @@ public class DefaultAssertionValidationContextBuilder
}
/**
- * Get the predicate which determines whether an Assertion's InResponseTo is required.
+ * Set the function for determining the valid InResponseTo.
+ *
+ * <p>
+ * Defaults to null.
+ * </p>
+ *
+ * @param function the function, may be null
+ */
+ public void setInResponseTo(final @Nonnull Function<ProfileRequestContext,String> function) {
+ inResponseTo = function;
+ }
+
+ /**
+ * Get the function for determining the valid InResponseTo.
+ *
+ * <p>
+ * Defaults to null.
+ * </p>
+ *
+ * @return the function
+ */
+ public Function<ProfileRequestContext,String> getInResponseTo() {
+ return inResponseTo;
+ }
+
+ /**
+ * Get the predicate which determines whether an Assertion SubjectConfirmationData InResponseTo is required.
*
* <p>
* Defaults to an always false predicate;
@@ -207,7 +251,7 @@ public class DefaultAssertionValidationContextBuilder
}
/**
- * Set the predicate which determines whether an Assertion's InResponseTo is required.
+ * Set the predicate which determines whether an Assertion SubjectConfirmationData InResponseTo is required.
*
* <p>
* Defaults to an always false predicate.
@@ -218,31 +262,109 @@ public class DefaultAssertionValidationContextBuilder
public void setInResponseToRequired(final @Nonnull Predicate<ProfileRequestContext> predicate) {
inResponseToRequired = Constraint.isNotNull(predicate, "InResponseTo required predicate was null");
}
-
+
/**
- * Set the function for determining the valid InResponseTo.
- *
+ * Get the predicate which determines whether an Assertion SubjectConfirmationData Recipient is required.
+ *
* <p>
- * Defaults to null.
+ * Defaults to an always false predicate;
* </p>
- *
- * @param function the function, may be null
+ *
+ * @return the predicate
*/
- public void setInResponseTo(final @Nonnull Function<ProfileRequestContext,String> function) {
- inResponseTo = function;
+ public Predicate<ProfileRequestContext> getRecipientRequired() {
+ return recipientRequired;
}
-
+
/**
- * Get the function for determining the valid InResponseTo.
- *
+ * Set the predicate which determines whether an Assertion SubjectConfirmationData Recipient is required.
+ *
* <p>
- * Defaults to null.
+ * Defaults to an always false predicate.
* </p>
- *
- * @return the function
+ *
+ * @param predicate the predicate, must be non-null
*/
- public Function<ProfileRequestContext,String> getInResponseTo() {
- return inResponseTo;
+ public void setRecipientRequired(final @Nonnull Predicate<ProfileRequestContext> predicate) {
+ recipientRequired = Constraint.isNotNull(predicate, "Recipient required predicate was null");
+ }
+
+ /**
+ * Get the predicate which determines whether an Assertion SubjectConfirmationData NotBefore is required.
+ *
+ * <p>
+ * Defaults to an always false predicate;
+ * </p>
+ *
+ * @return the predicate
+ */
+ public Predicate<ProfileRequestContext> getNotBeforeRequired() {
+ return notBeforeRequired;
+ }
+
+ /**
+ * Set the predicate which determines whether an Assertion SubjectConfirmationData NotBefore is required.
+ *
+ * <p>
+ * Defaults to an always false predicate.
+ * </p>
+ *
+ * @param predicate the predicate, must be non-null
+ */
+ public void setNotBeforeRequired(final @Nonnull Predicate<ProfileRequestContext> predicate) {
+ notBeforeRequired = Constraint.isNotNull(predicate, "NotBefore required predicate was null");
+ }
+
+ /**
+ * Get the predicate which determines whether an Assertion SubjectConfirmationData NotOnOrAfter is required.
+ *
+ * <p>
+ * Defaults to an always false predicate;
+ * </p>
+ *
+ * @return the predicate
+ */
+ public Predicate<ProfileRequestContext> getNotOnOrAfterRequired() {
+ return notOnOrAfterRequired;
+ }
+
+ /**
+ * Set the predicate which determines whether an Assertion SubjectConfirmationData NotOnOrAfter is required.
+ *
+ * <p>
+ * Defaults to an always false predicate.
+ * </p>
+ *
+ * @param predicate the predicate, must be non-null
+ */
+ public void setNotOnOrAfterRequired(final @Nonnull Predicate<ProfileRequestContext> predicate) {
+ notOnOrAfterRequired = Constraint.isNotNull(predicate, "NotOnOrAfter required predicate was null");
+ }
+
+ /**
+ * Get the predicate which determines whether an Assertion SubjectConfirmationData Address is required.
+ *
+ * <p>
+ * Defaults to an always false predicate;
+ * </p>
+ *
+ * @return the predicate
+ */
+ public Predicate<ProfileRequestContext> getAddressRequired() {
+ return addressRequired;
+ }
+
+ /**
+ * Set the predicate which determines whether an Assertion SubjectConfirmationData Address is required.
+ *
+ * <p>
+ * Defaults to an always false predicate.
+ * </p>
+ *
+ * @param predicate the predicate, must be non-null
+ */
+ public void setAddressRequired(final @Nonnull Predicate<ProfileRequestContext> predicate) {
+ addressRequired = Constraint.isNotNull(predicate, "Address required predicate was null");
}
/**
@@ -397,9 +519,15 @@ public class DefaultAssertionValidationContextBuilder
final Boolean checkAddressEnabled = Boolean.valueOf(getCheckAddress().test(input.getProfileRequestContext()));
// For SubjectConfirmationData
+ staticParams.put(SAML2AssertionValidationParameters.SC_RECIPIENT_REQUIRED,
+ Boolean.valueOf(getRecipientRequired().test(input.getProfileRequestContext())));
staticParams.put(SAML2AssertionValidationParameters.SC_VALID_RECIPIENTS, getValidRecipients(input));
+
+ staticParams.put(SAML2AssertionValidationParameters.SC_ADDRESS_REQUIRED,
+ 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_REQUIRED,
Boolean.valueOf(getInResponseToRequired().test(input.getProfileRequestContext())));
if (getInResponseTo() != null) {
@@ -407,6 +535,11 @@ public class DefaultAssertionValidationContextBuilder
getInResponseTo().apply(input.getProfileRequestContext()));
}
+ staticParams.put(SAML2AssertionValidationParameters.SC_NOT_BEFORE_REQUIRED,
+ Boolean.valueOf(getNotBeforeRequired().test(input.getProfileRequestContext())));
+ staticParams.put(SAML2AssertionValidationParameters.SC_NOT_ON_OR_AFTER_REQUIRED,
+ Boolean.valueOf(getNotOnOrAfterRequired().test(input.getProfileRequestContext())));
+
// For Audience Condition
staticParams.put(SAML2AssertionValidationParameters.COND_VALID_AUDIENCES, getValidAudiences(input));
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 3464b41..a7ed5f8 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
@@ -124,6 +124,30 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
}
@Test
+ public void testNoAddressAndRequired() throws AssertionValidationException {
+ subjectConfirmation.getSubjectConfirmationData().setAddress(null);
+
+ Map<String,Object> staticParams = buildBasicStaticParameters();
+ staticParams.put(SAML2AssertionValidationParameters.SC_ADDRESS_REQUIRED, Boolean.TRUE);
+ ValidationContext validationContext = new ValidationContext(staticParams);
+
+ Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
+ ValidationResult.INVALID);
+ }
+
+ @Test
+ public void testNoConfirmationDataAndAddressRequired() throws AssertionValidationException {
+ subjectConfirmation.setSubjectConfirmationData(null);
+
+ Map<String,Object> staticParams = buildBasicStaticParameters();
+ staticParams.put(SAML2AssertionValidationParameters.SC_ADDRESS_REQUIRED, Boolean.TRUE);
+ ValidationContext validationContext = new ValidationContext(staticParams);
+
+ Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
+ ValidationResult.INVALID);
+ }
+
+ @Test
public void testInvalidRecipient() throws AssertionValidationException {
subjectConfirmation.getSubjectConfirmationData().setRecipient("https://bogussp.example.com");
@@ -167,6 +191,30 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
}
@Test
+ public void testNoRecipientAndRequired() throws AssertionValidationException {
+ subjectConfirmation.getSubjectConfirmationData().setRecipient(null);
+
+ Map<String,Object> staticParams = buildBasicStaticParameters();
+ staticParams.put(SAML2AssertionValidationParameters.SC_RECIPIENT_REQUIRED, Boolean.TRUE);
+ ValidationContext validationContext = new ValidationContext(staticParams);
+
+ Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
+ ValidationResult.INVALID);
+ }
+
+ @Test
+ public void testNoConfirmationDataAndRecipientRequired() throws AssertionValidationException {
+ subjectConfirmation.setSubjectConfirmationData(null);
+
+ Map<String,Object> staticParams = buildBasicStaticParameters();
+ staticParams.put(SAML2AssertionValidationParameters.SC_RECIPIENT_REQUIRED, Boolean.TRUE);
+ ValidationContext validationContext = new ValidationContext(staticParams);
+
+ Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
+ ValidationResult.INVALID);
+ }
+
+ @Test
public void testInvalidNotBefore() throws AssertionValidationException {
// Adjust them both just so they make sense
subjectConfirmation.getSubjectConfirmationData().setNotBefore(Instant.now().plus(30, ChronoUnit.MINUTES));
@@ -189,6 +237,30 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
}
@Test
+ public void testNoNotBeforeAndRequired() throws AssertionValidationException {
+ subjectConfirmation.getSubjectConfirmationData().setNotBefore(null);
+
+ Map<String,Object> staticParams = buildBasicStaticParameters();
+ staticParams.put(SAML2AssertionValidationParameters.SC_NOT_BEFORE_REQUIRED, Boolean.TRUE);
+ ValidationContext validationContext = new ValidationContext(staticParams);
+
+ Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
+ ValidationResult.INVALID);
+ }
+
+ @Test
+ public void testNoConfirmationDataAndNotBeforeRequired() throws AssertionValidationException {
+ subjectConfirmation.setSubjectConfirmationData(null);
+
+ Map<String,Object> staticParams = buildBasicStaticParameters();
+ staticParams.put(SAML2AssertionValidationParameters.SC_NOT_BEFORE_REQUIRED, Boolean.TRUE);
+ ValidationContext validationContext = new ValidationContext(staticParams);
+
+ Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
+ ValidationResult.INVALID);
+ }
+
+ @Test
public void testInvalidNotOnOrAfter() throws AssertionValidationException {
// Adjust them both just so they make sense
subjectConfirmation.getSubjectConfirmationData().setNotBefore(Instant.now().minus(60, ChronoUnit.MINUTES));
@@ -211,6 +283,30 @@ public class AbstractSubjectConfirmationValidatorTest extends BaseAssertionValid
}
@Test
+ public void testNoNotOnOrAfterAndRequired() throws AssertionValidationException {
+ subjectConfirmation.getSubjectConfirmationData().setNotOnOrAfter(null);
+
+ Map<String,Object> staticParams = buildBasicStaticParameters();
+ staticParams.put(SAML2AssertionValidationParameters.SC_NOT_ON_OR_AFTER_REQUIRED, Boolean.TRUE);
+ ValidationContext validationContext = new ValidationContext(staticParams);
+
+ Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
+ ValidationResult.INVALID);
+ }
+
+ @Test
+ public void testNoConfirmationDataAndNotOnOrAfterRequired() throws AssertionValidationException {
+ subjectConfirmation.setSubjectConfirmationData(null);
+
+ Map<String,Object> staticParams = buildBasicStaticParameters();
+ staticParams.put(SAML2AssertionValidationParameters.SC_NOT_ON_OR_AFTER_REQUIRED, Boolean.TRUE);
+ ValidationContext validationContext = new ValidationContext(staticParams);
+
+ Assert.assertEquals(validator.validate(subjectConfirmation, getAssertion(), validationContext),
+ ValidationResult.INVALID);
+ }
+
+ @Test
public void testInvalidInResponseTo() throws AssertionValidationException {
subjectConfirmation.getSubjectConfirmationData().setInResponseTo("invalid");
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list