[java-opensaml] branch main updated: OSJ-380 - Logging of assertion validation is overwriting error messages
Scott Cantor
cantor.2 at osu.edu
Thu May 18 17:10:11 UTC 2023
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=bfb099a33ccb3a1096ff7a77742ddce894c0c16e
The following commit(s) were added to refs/heads/main by this push:
new bfb099a33 OSJ-380 - Logging of assertion validation is overwriting error messages
bfb099a33 is described below
commit bfb099a33ccb3a1096ff7a77742ddce894c0c16e
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu May 18 13:10:05 2023 -0400
OSJ-380 - Logging of assertion validation is overwriting error messages
https://shibboleth.atlassian.net/browse/OSJ-380
---
.../saml/common/assertion/ValidationContext.java | 19 ++---
.../saml/common/assertion/package-info.java | 4 +-
.../saml2/assertion/SAML20AssertionValidator.java | 96 +++++++++-------------
.../SAML2AssertionValidationParameters.java | 36 +++++---
.../saml/saml2/assertion/package-info.java | 4 +-
.../impl/AbstractSubjectConfirmationValidator.java | 59 +++++--------
.../assertion/impl/AssertionValidationSupport.java | 36 ++++----
.../AudienceRestrictionConditionValidator.java | 23 +++---
.../HolderOfKeySubjectConfirmationValidator.java | 29 +++----
.../impl/OneTimeUseConditionValidator.java | 9 +-
.../saml2/profile/impl/ValidateAssertions.java | 4 +-
...ecuritySAML20AssertionTokenSecurityHandler.java | 13 +--
.../assertion/tests/MockAssertionValidator.java | 4 +-
13 files changed, 146 insertions(+), 190 deletions(-)
diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/assertion/ValidationContext.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/assertion/ValidationContext.java
index 16c0c3b72..b779d31a6 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/assertion/ValidationContext.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/assertion/ValidationContext.java
@@ -17,8 +17,10 @@
package org.opensaml.saml.common.assertion;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.annotation.Nonnull;
@@ -30,7 +32,6 @@ import net.shibboleth.shared.annotation.constraint.NotLive;
import net.shibboleth.shared.annotation.constraint.Unmodifiable;
import net.shibboleth.shared.collection.CollectionSupport;
import net.shibboleth.shared.collection.LazyMap;
-import net.shibboleth.shared.primitive.StringSupport;
/**
* Context which holds state related to a single validation event.
@@ -45,7 +46,7 @@ public class ValidationContext {
@Nonnull private Map<String, Object> dynamicParameters;
/** Error messaging describing what validation check an assertion failed. */
- @Nullable private String validationFailureMessage;
+ @Nonnull private final List<String> validationFailureMessages;
/** Constructor. Creates a validation context with no global environment. */
public ValidationContext() {
@@ -65,6 +66,7 @@ public class ValidationContext {
staticParameters = Collections.unmodifiableMap(new HashMap<>(newStaticParameters));
}
dynamicParameters = new LazyMap<>();
+ validationFailureMessages = new ArrayList<>();
}
/**
@@ -90,17 +92,8 @@ public class ValidationContext {
*
* @return message describing why the validation process failed
*/
- @Nullable public String getValidationFailureMessage() {
- return validationFailureMessage;
- }
-
- /**
- * Sets the message describing why the validation process failed.
- *
- * @param message message describing why the validation process failed
- */
- public void setValidationFailureMessage(@Nullable final String message) {
- validationFailureMessage = StringSupport.trimOrNull(message);
+ @Nonnull @Live public List<String> getValidationFailureMessages() {
+ return validationFailureMessages;
}
}
\ No newline at end of file
diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/assertion/package-info.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/assertion/package-info.java
index 3c19f53b2..0d860de35 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/common/assertion/package-info.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/common/assertion/package-info.java
@@ -18,5 +18,7 @@
/**
* Common classes for validating SAML Assertions.
*/
+ at NonnullElements
+package org.opensaml.saml.common.assertion;
-package org.opensaml.saml.common.assertion;
\ No newline at end of file
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/SAML20AssertionValidator.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/SAML20AssertionValidator.java
index ccc5e2135..a1a67f140 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/SAML20AssertionValidator.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/SAML20AssertionValidator.java
@@ -379,7 +379,7 @@ public class SAML20AssertionValidator {
@Nonnull final ValidationContext context) throws AssertionValidationException {
if (assertion.getVersion() != SAMLVersion.VERSION_20) {
- context.setValidationFailureMessage(String.format(
+ context.getValidationFailureMessages().add(String.format(
"Assertion '%s' is not a SAML 2.0 version Assertion", assertion.getID()));
return ValidationResult.INVALID;
}
@@ -402,7 +402,7 @@ public class SAML20AssertionValidator {
final Instant issueInstant = assertion.getIssueInstant();
if (issueInstant == null) {
- context.setValidationFailureMessage(String.format(
+ context.getValidationFailureMessages().add(String.format(
"Assertion '%s' did not contain the required IssueInstant", assertion.getID()));
return ValidationResult.INVALID;
}
@@ -416,17 +416,18 @@ public class SAML20AssertionValidator {
// Check assertion wasn't issued in the future
if (issueInstant.isAfter(latestValid)) {
- log.warn("Assertion was not yet valid: IssueInstant: '{}', latest valid: '{}'", issueInstant, latestValid);
- context.setValidationFailureMessage("Assertion IssueInstant was invalid, issued in future");
+ context.getValidationFailureMessages().add(
+ String.format("Assertion was not yet valid: IssueInstant: '%s', latest valid: '%s'",
+ issueInstant, latestValid));
return ValidationResult.INVALID;
}
// Check assertion has not expired
if (expiration.isBefore(now)) {
- log.warn("Assertion IssueInstant was expired: IssueInstant: '{}', expiration: '{}', now: '{}'",
- issueInstant, expiration, now);
- context.setValidationFailureMessage("Assertion IssueInstant was invalid, expired");
+ context.getValidationFailureMessages().add(
+ String.format("Assertion IssueInstant was expired: IssueInstant: '{}', expiration: '{}', now: '{}'",
+ issueInstant, expiration, now));
return ValidationResult.INVALID;
}
@@ -453,8 +454,7 @@ public class SAML20AssertionValidator {
issuer = StringSupport.trimOrNull(issuerElement.getValue());
}
if (issuer == null) {
- log.warn("Assertion Issuer was missing and was required");
- context.setValidationFailureMessage("Assertion Issuer was missing and was required");
+ context.getValidationFailureMessages().add("Assertion Issuer was missing and was required");
return ValidationResult.INVALID;
}
@@ -465,9 +465,7 @@ public class SAML20AssertionValidator {
validIssuers = (Set<String>) context.getStaticParameters().get(
SAML2AssertionValidationParameters.VALID_ISSUERS);
} catch (final ClassCastException e) {
- log.warn("The value of the static validation parameter '{}' was not java.util.Set<String>",
- SAML2AssertionValidationParameters.VALID_ISSUERS);
- context.setValidationFailureMessage("Unable to determine list of valid issuers");
+ context.getValidationFailureMessages().add("Unable to determine list of valid issuers");
return ValidationResult.INDETERMINATE;
}
if (validIssuers == null || validIssuers.isEmpty()) {
@@ -486,9 +484,7 @@ public class SAML20AssertionValidator {
return ValidationResult.VALID;
}
- log.debug("Failed to match Issuer to any supplied valid issuers: {}", validIssuers);
-
- context.setValidationFailureMessage(String.format(
+ context.getValidationFailureMessages().add(String.format(
"Issuer of Assertion '%s' did not match any valid issuers", assertion.getID()));
return ValidationResult.INVALID;
}
@@ -515,7 +511,7 @@ public class SAML20AssertionValidator {
// Validate params and requirements
if (!token.isSigned()) {
if (signatureRequired) {
- context.setValidationFailureMessage("Assertion was required to be signed, but was not");
+ context.getValidationFailureMessages().add("Assertion was required to be signed, but was not");
return ValidationResult.INVALID;
}
log.debug("Assertion was not required to be signed, and was not signed. "
@@ -541,8 +537,8 @@ public class SAML20AssertionValidator {
final SignatureTrustEngine signatureTrustEngine = getSignatureValidationTrustEngine(token, context);
if (signatureTrustEngine == null) {
- log.warn("Signature validation was necessary, but no signature trust engine was available");
- context.setValidationFailureMessage("Assertion signature could not be evaluated due to internal error");
+ context.getValidationFailureMessages().add(
+ "Signature validation was necessary, but no signature trust engine was available");
return ValidationResult.INDETERMINATE;
}
@@ -566,9 +562,8 @@ public class SAML20AssertionValidator {
log.warn("No SignaturePrevalidator was available, skipping pre-validation");
}
} catch (final SignatureException e) {
- final String msg = String.format("Assertion Signature failed pre-validation: %s", e.getMessage());
- log.warn(msg);
- context.setValidationFailureMessage(msg);
+ context.getValidationFailureMessages().add(
+ String.format("Assertion Signature failed pre-validation: %s", e.getMessage()));
return ValidationResult.INVALID;
}
@@ -580,20 +575,16 @@ public class SAML20AssertionValidator {
token.getID(), tokenIssuer);
return ValidationResult.VALID;
}
- final String msg = String.format(
- "Signature of Assertion '%s' from Issuer '%s' was not valid", token.getID(), tokenIssuer);
- log.warn(msg);
- context.setValidationFailureMessage(msg);
+ context.getValidationFailureMessages().add(
+ String.format("Signature of Assertion '%s' from Issuer '%s' was not valid",
+ token.getID(), tokenIssuer));
return ValidationResult.INVALID;
} catch (final SecurityException e) {
- final String msg = String.format(
- "A problem was encountered evaluating the signature over Assertion with ID '%s': %s",
- token.getID(), e.getMessage());
- log.warn(msg);
- context.setValidationFailureMessage(msg);
+ context.getValidationFailureMessages().add(
+ String.format("A problem was encountered evaluating the signature over Assertion with ID '%s': %s",
+ token.getID(), e.getMessage()));
return ValidationResult.INDETERMINATE;
}
-
}
/**
@@ -709,22 +700,15 @@ public class SAML20AssertionValidator {
}
if (validator == null) {
- final String msg = String.format(
- "Unknown Condition '%s' of type '%s' in assertion '%s'",
- condition.getElementQName(), condition.getSchemaType(), assertion.getID());
- log.debug(msg);
- context.setValidationFailureMessage(msg);
+ context.getValidationFailureMessages().add(
+ String.format("Unknown Condition '%s' of type '%s' in assertion '%s'",
+ condition.getElementQName(), condition.getSchemaType(), assertion.getID()));
return ValidationResult.INDETERMINATE;
}
if (validator.validate(condition, assertion, context) != ValidationResult.VALID) {
- String msg = String.format(
- "Condition '%s' of type '%s' in assertion '%s' was not valid.",
- condition.getElementQName(), condition.getSchemaType(), assertion.getID());
- if (context.getValidationFailureMessage() != null) {
- msg = msg + ": " + context.getValidationFailureMessage();
- }
- log.debug(msg);
- context.setValidationFailureMessage(msg);
+ context.getValidationFailureMessages().add(
+ String.format("Condition '%s' of type '%s' in assertion '%s' was not valid.",
+ condition.getElementQName(), condition.getSchemaType(), assertion.getID()));
return ValidationResult.INVALID;
}
}
@@ -754,8 +738,7 @@ public class SAML20AssertionValidator {
final Conditions conditions = assertion.getConditions();
if (conditions == null || conditions.getConditions().isEmpty()) {
- log.warn("At least 1 Condition was indicated as required, but Assertion contained no Conditions");
- context.setValidationFailureMessage(
+ context.getValidationFailureMessages().add(
"At least 1 Condition was indicated as required, but Assertion contained no Conditions");
return ValidationResult.INVALID;
}
@@ -764,13 +747,9 @@ public class SAML20AssertionValidator {
assert requiredCondition != null;
final List<Condition> found = conditions.getConditions(requiredCondition);
if (found == null || found.isEmpty()) {
- String msg = String.format("Condition '%s' was required, but was not found in assertion '%s'",
- requiredCondition, assertion.getID());
- if (context.getValidationFailureMessage() != null) {
- msg = msg + ": " + context.getValidationFailureMessage();
- }
- log.warn(msg);
- context.setValidationFailureMessage(msg);
+ context.getValidationFailureMessages().add(
+ String.format("Condition '%s' was required, but was not found in assertion '%s'",
+ requiredCondition, assertion.getID()));
return ValidationResult.INVALID;
}
}
@@ -803,7 +782,7 @@ public class SAML20AssertionValidator {
log.debug("Evaluating Conditions NotBefore '{}' against 'skewed now' time '{}'",
notBefore, now.plus(clockSkew));
if (notBefore != null && notBefore.isAfter(now.plus(clockSkew))) {
- context.setValidationFailureMessage(String.format(
+ context.getValidationFailureMessages().add(String.format(
"Assertion '%s' with NotBefore condition of '%s' is not yet valid", assertion.getID(), notBefore));
return ValidationResult.INVALID;
}
@@ -812,7 +791,7 @@ public class SAML20AssertionValidator {
log.debug("Evaluating Conditions NotOnOrAfter '{}' against 'skewed now' time '{}'",
notOnOrAfter, now.minus(clockSkew));
if (notOnOrAfter != null && notOnOrAfter.isBefore(now.minus(clockSkew))) {
- context.setValidationFailureMessage(String.format(
+ context.getValidationFailureMessages().add(String.format(
"Assertion '%s' with NotOnOrAfter condition of '%s' is no longer valid", assertion.getID(),
notOnOrAfter));
return ValidationResult.INVALID;
@@ -865,10 +844,9 @@ public class SAML20AssertionValidator {
}
}
- final String msg = String.format(
- "No subject confirmation methods were met for assertion with ID '%s'", assertion.getID());
- log.debug(msg);
- context.setValidationFailureMessage(msg);
+ context.getValidationFailureMessages().add(
+ String.format("No subject confirmation methods were met for assertion with ID '%s'",
+ assertion.getID()));
return ValidationResult.INVALID;
}
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 f6f8d9df2..90e60c51d 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
@@ -55,7 +55,8 @@ public final class SAML2AssertionValidationParameters {
/**
* Carries the {@link org.opensaml.saml.saml2.core.SubjectConfirmation} that confirmed the subject.
*/
- @Nonnull @NotEmpty public static final String CONFIRMED_SUBJECT_CONFIRMATION = STD_PREFIX + ".ConfirmedSubjectConfirmation";
+ @Nonnull @NotEmpty public static final String CONFIRMED_SUBJECT_CONFIRMATION =
+ STD_PREFIX + ".ConfirmedSubjectConfirmation";
/**
* Carries a {@link java.util.Set}<code><</code>{@link java.lang.String}<code>></code>
@@ -73,20 +74,23 @@ public final class SAML2AssertionValidationParameters {
* Carries a {@link net.shibboleth.shared.resolver.CriteriaSet} which will be used as the
* input to a {@link org.opensaml.xmlsec.signature.support.SignatureTrustEngine}.
*/
- @Nonnull @NotEmpty public static final String SIGNATURE_VALIDATION_CRITERIA_SET = STD_PREFIX + ".SignatureValidationCriteriaSet";
+ @Nonnull @NotEmpty public static final String SIGNATURE_VALIDATION_CRITERIA_SET =
+ STD_PREFIX + ".SignatureValidationCriteriaSet";
/**
* Carries a {@link org.opensaml.xmlsec.signature.support.SignatureTrustEngine} which will be used
* to validate the Assertion signature.
*/
- @Nonnull @NotEmpty public static final String SIGNATURE_VALIDATION_TRUST_ENGINE = STD_PREFIX + ".SignatureValidationTrustEngine";
+ @Nonnull @NotEmpty public static final String SIGNATURE_VALIDATION_TRUST_ENGINE =
+ STD_PREFIX + ".SignatureValidationTrustEngine";
/**
* Carries a {@link org.opensaml.xmlsec.signature.support.SignaturePrevalidator} which will be used
* to pre-validate the Assertion signature.
*
*/
- @Nonnull @NotEmpty public static final String SIGNATURE_VALIDATION_PREVALIDATOR = STD_PREFIX + ".SignatureValidationPrevalidator";
+ @Nonnull @NotEmpty public static final String SIGNATURE_VALIDATION_PREVALIDATOR =
+ STD_PREFIX + ".SignatureValidationPrevalidator";
/**
* Carries a {@link java.lang.Boolean} flag which indicates whether
@@ -98,7 +102,8 @@ public final class SAML2AssertionValidationParameters {
* Carries a {@link java.lang.Boolean} flag which indicates whether
* {@link org.opensaml.saml.saml2.core.SubjectConfirmationData} NotOnOrAfter is required.
*/
- @Nonnull @NotEmpty public static final String SC_NOT_ON_OR_AFTER_REQUIRED = STD_PREFIX + SC_INFIX + ".NoOnOrAfterRequired";
+ @Nonnull @NotEmpty 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
@@ -136,13 +141,15 @@ public final class SAML2AssertionValidationParameters {
* Carries a {@link java.lang.Boolean} flag which indicates whether
* {@link org.opensaml.saml.saml2.core.SubjectConfirmationData} InResponseTo is required.
*/
- @Nonnull @NotEmpty public static final String SC_IN_RESPONSE_TO_REQUIRED = STD_PREFIX + SC_INFIX + ".InResponseToRequired";
+ @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.
*/
- @Nonnull @NotEmpty public static final String SC_VALID_IN_RESPONSE_TO = STD_PREFIX + SC_INFIX + ".ValidInResponseTo";
+ @Nonnull @NotEmpty public static final String SC_VALID_IN_RESPONSE_TO =
+ STD_PREFIX + SC_INFIX + ".ValidInResponseTo";
/**
* Carries the {@link java.security.PublicKey} used by the presenter.
@@ -152,19 +159,22 @@ public final class SAML2AssertionValidationParameters {
/**
* Carries the {@link java.security.cert.X509Certificate} used by the presenter.
*/
- @Nonnull @NotEmpty public static final String SC_HOK_PRESENTER_CERT = STD_PREFIX + SC_INFIX + ".HoK.PresenterCertificate";
+ @Nonnull @NotEmpty public static final String SC_HOK_PRESENTER_CERT =
+ STD_PREFIX + SC_INFIX + ".HoK.PresenterCertificate";
/**
* Carries the {@link org.opensaml.xmlsec.signature.KeyInfo} that successfully confirmed the subject
* via holder-of-key subject confirmation.
*/
- @Nonnull @NotEmpty public static final String SC_HOK_CONFIRMED_KEYINFO = STD_PREFIX + SC_INFIX + ".HoK.ConfirmedKeyInfo";
+ @Nonnull @NotEmpty public static final String SC_HOK_CONFIRMED_KEYINFO =
+ STD_PREFIX + SC_INFIX + ".HoK.ConfirmedKeyInfo";
/**
* Carries a {@link java.util.Set}<code><</code>{@link javax.xml.namespace.QName}<code>></code>
* of required conditions which must be present in the assertion.
*/
- @Nonnull @NotEmpty public static final String COND_REQUIRED_CONDITIONS = STD_PREFIX + COND_INFIX + ".RequiredConditions";
+ @Nonnull @NotEmpty public static final String COND_REQUIRED_CONDITIONS =
+ STD_PREFIX + COND_INFIX + ".RequiredConditions";
/**
* Carries a {@link java.util.Set}<code><</code>{@link java.lang.String}<code>></code>
@@ -178,7 +188,8 @@ public final class SAML2AssertionValidationParameters {
* Carries a {@link java.time.Duration} representing the per-invocation value for the Assertion
* replay cache expiration.
*/
- @Nonnull @NotEmpty public static final String COND_ONE_TIME_USE_EXPIRES = STD_PREFIX + COND_INFIX + ".OneTimeUseExpires";
+ @Nonnull @NotEmpty public static final String COND_ONE_TIME_USE_EXPIRES =
+ STD_PREFIX + COND_INFIX + ".OneTimeUseExpires";
/**
* Carries a {@link java.lang.Boolean} flag which indicates whether the
@@ -200,7 +211,8 @@ public final class SAML2AssertionValidationParameters {
* Carries a {@link java.time.Duration} used to evaluate the
* allowed value of an AuthnInstant attribute of an {@link AuthnStatement}.
*/
- @Nonnull @NotEmpty public static final String STMT_AUTHN_MAX_TIME = STD_PREFIX + STMT_INFIX + ".Authn.MaxTimeSinceAuthn";
+ @Nonnull @NotEmpty public static final String STMT_AUTHN_MAX_TIME =
+ STD_PREFIX + STMT_INFIX + ".Authn.MaxTimeSinceAuthn";
/** Constructor. */
diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/package-info.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/package-info.java
index 6e7a14dc0..3e8874493 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/package-info.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/saml2/assertion/package-info.java
@@ -18,5 +18,7 @@
/**
* Interfaces and API classes for validating SAML 2 Assertions.
*/
+ at NonnullElements
+package org.opensaml.saml.saml2.assertion;
-package org.opensaml.saml.saml2.assertion;
\ No newline at end of file
+import net.shibboleth.shared.annotation.constraint.NonnullElements;
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 7037a2c46..f82c34144 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
@@ -144,8 +144,7 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
} else {
if (inResponseToRequired || recipientRequired || notOnOrAfterRequired || notBeforeRequired
|| addressRequired) {
- log.warn("SubjectConfirmationData was null, and one of more data elements were required");
- context.setValidationFailureMessage(
+ context.getValidationFailureMessages().add(
"SubjectConfirmationData was null and one or more data elements were required");
return ValidationResult.INVALID;
}
@@ -250,8 +249,7 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
StringSupport.trimOrNull(confirmationData.getInResponseTo());
if (inResponseTo == null) {
if (required) {
- log.warn("SubjectConfirmationData/@InResponseTo was missing and was required");
- context.setValidationFailureMessage(
+ context.getValidationFailureMessages().add(
"SubjectConfirmationData/@InResponseTo was missing and was required");
return ValidationResult.INVALID;
}
@@ -265,16 +263,13 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
validInResponseTo = (String) context.getStaticParameters().get(
SAML2AssertionValidationParameters.SC_VALID_IN_RESPONSE_TO);
} catch (final ClassCastException e) {
- log.warn("The value of the static validation parameter '{}' was not java.lang.String",
- SAML2AssertionValidationParameters.SC_VALID_IN_RESPONSE_TO);
- context.setValidationFailureMessage(
+ context.getValidationFailureMessages().add(
"Unable to determine valid subject confirmation InResponseTo");
return ValidationResult.INDETERMINATE;
}
if (validInResponseTo == null) {
- log.warn("Valid InResponseTo was not available from the validation context, "
+ context.getValidationFailureMessages().add("Valid InResponseTo was not available from the validation context, "
+ "unable to evaluate SubjectConfirmationData at InResponseTo");
- context.setValidationFailureMessage("Unable to determine valid subject confirmation InResponseTo");
return ValidationResult.INDETERMINATE;
}
@@ -283,11 +278,9 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
return ValidationResult.VALID;
}
- log.debug("Failed to match SubjectConfirmationData at InResponse to the valid value: {}", validInResponseTo);
-
- context.setValidationFailureMessage(String.format(
- "Subject confirmation InResponseTo for assertion '%s' did not match the valid value",
- assertion.getID()));
+ context.getValidationFailureMessages().add(String.format(
+ "Subject confirmation InResponseTo for assertion '%s' did not match the valid value: %s",
+ assertion.getID(), validInResponseTo));
return ValidationResult.INVALID;
}
@@ -310,8 +303,7 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
final Instant notBefore = confirmationData.getNotBefore();
if (notBefore == null) {
if (required) {
- log.warn("SubjectConfirmationData/@NotBefore was missing and was required");
- context.setValidationFailureMessage(
+ context.getValidationFailureMessages().add(
"SubjectConfirmationData/@NotBefore was missing and was required");
return ValidationResult.INVALID;
}
@@ -323,7 +315,7 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
log.debug("Evaluating SubjectConfirmationData NotBefore '{}' against 'skewed now' time '{}'",
notBefore, skewedNow);
if (notBefore != null && notBefore.isAfter(skewedNow)) {
- context.setValidationFailureMessage(String.format(
+ context.getValidationFailureMessages().add(String.format(
"Subject confirmation, in assertion '%s', with NotBefore condition of '%s' is not yet valid",
assertion.getID(), notBefore));
return ValidationResult.INVALID;
@@ -351,8 +343,7 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
final Instant notOnOrAfter = confirmationData.getNotOnOrAfter();
if (notOnOrAfter == null) {
if (required) {
- log.warn("SubjectConfirmationData/@NotOnOrAfter was missing and was required");
- context.setValidationFailureMessage(
+ context.getValidationFailureMessages().add(
"SubjectConfirmationData/@NotOnOrAfter was missing and was required");
return ValidationResult.INVALID;
}
@@ -364,7 +355,7 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
log.debug("Evaluating SubjectConfirmationData NotOnOrAfter '{}' against 'skewed now' time '{}'",
notOnOrAfter, skewedNow);
if (notOnOrAfter != null && notOnOrAfter.isBefore(skewedNow)) {
- context.setValidationFailureMessage(String.format(
+ context.getValidationFailureMessages().add(String.format(
"Subject confirmation, in assertion '%s', with NotOnOrAfter condition of '%s' is no longer valid",
assertion.getID(), notOnOrAfter));
return ValidationResult.INVALID;
@@ -393,32 +384,28 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
StringSupport.trimOrNull(confirmationData.getRecipient());
if (recipient == null) {
if (required) {
- log.warn("SubjectConfirmationData/@Recipient was missing and was required");
- context.setValidationFailureMessage(
+ context.getValidationFailureMessages().add(
"SubjectConfirmationData/@Recipient was missing and was required");
return ValidationResult.INVALID;
}
return ValidationResult.VALID;
}
- log.debug("Evaluating SubjectConfirmationData at Recipient of : {}", recipient);
+ log.debug("Evaluating SubjectConfirmationData at Recipient of: {}", recipient);
final Set<String> validRecipients;
try {
validRecipients = (Set<String>) context.getStaticParameters().get(
SAML2AssertionValidationParameters.SC_VALID_RECIPIENTS);
} catch (final ClassCastException e) {
- log.warn("The value of the static validation parameter '{}' was not java.util.Set<String>",
- SAML2AssertionValidationParameters.SC_VALID_RECIPIENTS);
- context.setValidationFailureMessage(
+ context.getValidationFailureMessages().add(
"Unable to determine list of valid subject confirmation recipient endpoints");
return ValidationResult.INDETERMINATE;
}
if (validRecipients == null || validRecipients.isEmpty()) {
- log.warn("Set of valid recipient URI's was not available from the validation context, "
- + "unable to evaluate SubjectConfirmationData at Recipient");
- context.setValidationFailureMessage(
- "Unable to determine list of valid subject confirmation recipient endpoints");
+ context.getValidationFailureMessages().add(
+ "Set of valid recipient URI's was not available from the validation context, "
+ + "unable to evaluate SubjectConfirmationData at Recipient");
return ValidationResult.INDETERMINATE;
}
@@ -426,13 +413,10 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
log.debug("Matched valid recipient: {}", recipient);
return ValidationResult.VALID;
}
-
- log.debug("Failed to match SubjectConfirmationData at Recipient to any supplied valid recipients: {}",
- validRecipients);
- context.setValidationFailureMessage(String.format(
- "Subject confirmation recipient for assertion '%s' did not match any valid recipients", assertion
- .getID()));
+ context.getValidationFailureMessages().add(String.format(
+ "Subject confirmation recipient for assertion '%s' did not match any valid recipients: %s",
+ assertion.getID(), validRecipients));
return ValidationResult.INVALID;
}
@@ -463,8 +447,7 @@ public abstract class AbstractSubjectConfirmationValidator implements SubjectCon
final String address = StringSupport.trimOrNull(confirmationData.getAddress());
if (address == null) {
if (required) {
- log.warn("SubjectConfirmationData/@Address was missing and was required");
- context.setValidationFailureMessage(
+ context.getValidationFailureMessages().add(
"SubjectConfirmationData/@Address was missing and was required");
return ValidationResult.INVALID;
}
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AssertionValidationSupport.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AssertionValidationSupport.java
index 8098310ea..81dc80547 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AssertionValidationSupport.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AssertionValidationSupport.java
@@ -19,7 +19,6 @@ package org.opensaml.saml.saml2.assertion.impl;
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.util.Arrays;
import java.util.Set;
import javax.annotation.Nonnull;
@@ -29,7 +28,9 @@ import org.opensaml.saml.common.assertion.ValidationContext;
import org.opensaml.saml.common.assertion.ValidationResult;
import org.opensaml.saml.saml2.core.Assertion;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
/**
* Support methods for assertion validation.
@@ -37,7 +38,7 @@ import org.slf4j.LoggerFactory;
public final class AssertionValidationSupport {
/** Logger. */
- private static final Logger LOG = LoggerFactory.getLogger(AssertionValidationSupport.class);
+ @Nonnull private static final Logger LOG = LoggerFactory.getLogger(AssertionValidationSupport.class);
/** Constructor. */
private AssertionValidationSupport() { }
@@ -69,33 +70,29 @@ public final class AssertionValidationSupport {
try {
confirmingAddresses = InetAddress.getAllByName(address);
} catch (final UnknownHostException e) {
- LOG.warn("The {} value '{}' in assertion '{}' can not be resolved to a valid set of IP address(s)",
- description, address, assertion.getID());
- context.setValidationFailureMessage(String.format(
+ context.getValidationFailureMessages().add(String.format(
"%s '%s' is not resolvable to hostname or IP address", description, address));
return ValidationResult.INDETERMINATE;
}
if (LOG.isDebugEnabled()) {
- LOG.debug("{} was resolved to addresses: {}", description, Arrays.asList(confirmingAddresses));
+ assert confirmingAddresses != null;
+ LOG.debug("{} was resolved to addresses: {}", description, CollectionSupport.listOf(confirmingAddresses));
}
final Set<InetAddress> validAddresses;
try {
validAddresses = (Set<InetAddress>) context.getStaticParameters().get(validAddressesParam);
} catch (final ClassCastException e) {
- LOG.warn("The value of the static validation parameter '{}' was not a java.util.Set<InetAddress>",
- validAddressesParam);
- context.setValidationFailureMessage(String.format("Unable to determine list of valid values for %s",
- description));
+ context.getValidationFailureMessages().add(
+ String.format("Unable to determine list of valid values for %s", description));
return ValidationResult.INDETERMINATE;
}
if (validAddresses == null || validAddresses.isEmpty()) {
- LOG.warn("Set of valid addresses was not available from the validation context, unable to evaluate {}",
- description);
- context.setValidationFailureMessage(String.format("Unable to determine list of valid values for %s",
- description));
+ context.getValidationFailureMessages().add(String.format(
+ "Set of valid addresses was not available from the validation context, unable to evaluate %s",
+ description));
return ValidationResult.INDETERMINATE;
}
@@ -106,11 +103,10 @@ public final class AssertionValidationSupport {
}
}
- LOG.debug("Failed to match {} to any supplied valid addresses: {}", description, validAddresses);
-
- context.setValidationFailureMessage(String.format(
- "%s for assertion '%s' did not match any valid addresses", description, assertion.getID()));
+ context.getValidationFailureMessages().add(
+ String.format("%s for assertion '%s' did not match supplied valid addresses: %s",
+ description, assertion.getID(), validAddresses));
return ValidationResult.INVALID;
}
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AudienceRestrictionConditionValidator.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AudienceRestrictionConditionValidator.java
index 5e6b97524..06609543d 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AudienceRestrictionConditionValidator.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/AudienceRestrictionConditionValidator.java
@@ -86,15 +86,13 @@ public class AudienceRestrictionConditionValidator implements ConditionValidator
validAudiences = (Set<String>) context.getStaticParameters().get(
SAML2AssertionValidationParameters.COND_VALID_AUDIENCES);
} catch (final ClassCastException e) {
- log.warn("The value of the static validation parameter '{}' was not java.util.Set<String>",
- SAML2AssertionValidationParameters.COND_VALID_AUDIENCES);
- context.setValidationFailureMessage("Unable to determine list of valid audiences");
+ context.getValidationFailureMessages().add("Unable to determine list of valid audiences");
return ValidationResult.INDETERMINATE;
}
if (validAudiences == null || validAudiences.isEmpty()) {
- log.warn("Set of valid audiences was not available from the validation context, "
- + "unable to evaluate AudienceRestriction Condition");
- context.setValidationFailureMessage("Unable to determine list of valid audiences");
+ context.getValidationFailureMessages().add(
+ "Set of valid audiences was not available from the validation context, "
+ + "unable to evaluate AudienceRestriction Condition");
return ValidationResult.INDETERMINATE;
}
log.debug("Evaluating the Assertion's AudienceRestriction/Audience values "
@@ -104,9 +102,9 @@ public class AudienceRestrictionConditionValidator implements ConditionValidator
final AudienceRestriction audienceRestriction = (AudienceRestriction) condition;
final List<Audience> audiences = audienceRestriction.getAudiences();
if (audiences == null || audiences.isEmpty()) {
- context.setValidationFailureMessage(String.format(
- "'%s' condition in assertion '%s' is malformed as it does not contain any audiences",
- getServicedCondition(), assertion.getID()));
+ context.getValidationFailureMessages().add(
+ String.format("'%s' condition in assertion '%s' is malformed as it does not contain any audiences",
+ getServicedCondition(), assertion.getID()));
return ValidationResult.INVALID;
}
@@ -118,10 +116,9 @@ public class AudienceRestrictionConditionValidator implements ConditionValidator
}
}
- final String msg = String.format(
- "None of the audiences within Assertion '%s' matched the list of valid audiances", assertion.getID());
- log.debug(msg);
- context.setValidationFailureMessage(msg);
+ context.getValidationFailureMessages().add(String.format(
+ "None of the audiences within Assertion '%s' matched the list of valid audiances", assertion.getID()));
return ValidationResult.INVALID;
}
+
}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/HolderOfKeySubjectConfirmationValidator.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/HolderOfKeySubjectConfirmationValidator.java
index 6b68a6259..e77c47de9 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/HolderOfKeySubjectConfirmationValidator.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/HolderOfKeySubjectConfirmationValidator.java
@@ -29,6 +29,7 @@ import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
import javax.xml.namespace.QName;
+import net.shibboleth.shared.annotation.constraint.Live;
import net.shibboleth.shared.collection.LazyList;
import net.shibboleth.shared.collection.Pair;
import net.shibboleth.shared.primitive.LoggerFactory;
@@ -132,19 +133,17 @@ public class HolderOfKeySubjectConfirmationValidator extends AbstractSubjectConf
log.debug("Attempting holder-of-key subject confirmation");
if (!isValidConfirmationDataType(confirmationData)) {
- final String msg = String.format(
- "Subject confirmation data is not of type '%s'", KeyInfoConfirmationDataType.TYPE_NAME);
- log.debug(msg);
- context.setValidationFailureMessage(msg);
+ context.getValidationFailureMessages().add(
+ String.format("Subject confirmation data is not of type '%s'",
+ KeyInfoConfirmationDataType.TYPE_NAME));
return ValidationResult.INVALID;
}
final List<KeyInfo> possibleKeys = getSubjectConfirmationKeyInformation(confirmationData, assertion, context);
if (possibleKeys.isEmpty()) {
- final String msg = String.format(
- "No key information for holder of key subject confirmation in assertion '%s'", assertion.getID());
- log.debug(msg);
- context.setValidationFailureMessage(msg);
+ context.getValidationFailureMessages().add(
+ String.format("No key information for holder of key subject confirmation in assertion '%s'",
+ assertion.getID()));
return ValidationResult.INVALID;
}
@@ -152,14 +151,14 @@ public class HolderOfKeySubjectConfirmationValidator extends AbstractSubjectConf
try {
keyCertPair = getKeyAndCertificate(context);
} catch (final IllegalArgumentException e) {
- log.warn("Problem with the validation context presenter key/cert params: {}", e.getMessage());
- context.setValidationFailureMessage("Unable to obtain presenter key/cert params from validation context");
+ context.getValidationFailureMessages().add(String.format(
+ "Unable to obtain presenter key/cert params from validation context: %s", e.getMessage()));
return ValidationResult.INDETERMINATE;
}
if (keyCertPair.getFirst() == null && keyCertPair.getSecond() == null) {
- log.debug("Neither the presenter's certificate nor its public key were provided");
- context.setValidationFailureMessage("Neither the presenter's certificate nor its public key were provided");
+ context.getValidationFailureMessages().add(
+ "Neither the presenter's certificate nor its public key were provided");
return ValidationResult.INDETERMINATE;
}
@@ -265,15 +264,13 @@ public class HolderOfKeySubjectConfirmationValidator extends AbstractSubjectConf
* @throws AssertionValidationException if there is a problem processing the SubjectConfirmation
*
*/
- @Nonnull protected List<KeyInfo> getSubjectConfirmationKeyInformation(
+ @Nonnull @Live protected List<KeyInfo> getSubjectConfirmationKeyInformation(
@Nonnull final SubjectConfirmationData confirmationData, @Nonnull final Assertion assertion,
@Nonnull final ValidationContext context) throws AssertionValidationException {
final List<KeyInfo> keyInfos = new LazyList<>();
for (final XMLObject object : confirmationData.getUnknownXMLObjects(KeyInfo.DEFAULT_ELEMENT_NAME)) {
- if (object != null) {
- keyInfos.add((KeyInfo) object);
- }
+ keyInfos.add((KeyInfo) object);
}
log.debug("Found '{}' KeyInfo children of SubjectConfirmationData", keyInfos.size());
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidator.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidator.java
index a5c7d2cd9..227a5313c 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidator.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/assertion/impl/OneTimeUseConditionValidator.java
@@ -111,14 +111,15 @@ public class OneTimeUseConditionValidator implements ConditionValidator {
if (!(condition instanceof OneTimeUse)
&& !Objects.equals(condition.getElementQName(), getServicedCondition())) {
- log.warn("Condition '{}' of type '{}' in assertion '{}' was not an '{}' condition. Unable to process.",
- new Object[] { condition.getElementQName(), condition.getSchemaType(), assertion.getID(),
- getServicedCondition(), });
+ context.getValidationFailureMessages().add(
+ String.format("Condition '%s' of type '%s' in assertion '%s' was not an '%s' condition",
+ condition.getElementQName(), condition.getSchemaType(), assertion.getID(),
+ getServicedCondition()));
return ValidationResult.INDETERMINATE;
}
if (!replayCache.check(CACHE_CONTEXT, getCacheValue(assertion), getExpires(assertion, context))) {
- context.setValidationFailureMessage(String.format(
+ context.getValidationFailureMessages().add(String.format(
"Assertion '%s' has a one time use condition and has been used before", assertion.getID()));
return ValidationResult.INVALID;
}
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/profile/impl/ValidateAssertions.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/profile/impl/ValidateAssertions.java
index 60522c33c..538246b2b 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/profile/impl/ValidateAssertions.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/profile/impl/ValidateAssertions.java
@@ -270,8 +270,8 @@ public class ValidateAssertions extends AbstractProfileAction {
log.debug("{} Assertion validation result was: {}", getLogPrefix(), validationResult);
if (validationResult != ValidationResult.VALID) {
- log.info("{} Assertion validation failure msg was: {}",
- getLogPrefix(), validationContext.getValidationFailureMessage());
+ log.info("{} Assertion validation failure(s): {}", getLogPrefix(),
+ validationContext.getValidationFailureMessages());
}
assertion.getObjectMetadata().put(new ValidationProcessingData(validationContext, validationResult));
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/wssecurity/messaging/impl/WSSecuritySAML20AssertionTokenSecurityHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/wssecurity/messaging/impl/WSSecuritySAML20AssertionTokenSecurityHandler.java
index f2eabb597..d101c06ca 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/wssecurity/messaging/impl/WSSecuritySAML20AssertionTokenSecurityHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/wssecurity/messaging/impl/WSSecuritySAML20AssertionTokenSecurityHandler.java
@@ -43,8 +43,6 @@ import org.opensaml.soap.wssecurity.messaging.Token.ValidationStatus;
import org.opensaml.soap.wssecurity.messaging.WSSecurityContext;
import org.slf4j.Logger;
-import com.google.common.base.Strings;
-
import jakarta.servlet.http.HttpServletRequest;
import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
import net.shibboleth.shared.collection.CollectionSupport;
@@ -292,11 +290,6 @@ public class WSSecuritySAML20AssertionTokenSecurityHandler extends AbstractMessa
log.debug("Assertion token validation result was: {}", validationResult);
- String validationMsg = validationContext.getValidationFailureMessage();
- if (Strings.isNullOrEmpty(validationMsg)) {
- validationMsg = "unspecified";
- }
-
switch (validationResult) {
case VALID:
token.setValidationStatus(ValidationStatus.VALID);
@@ -304,7 +297,8 @@ public class WSSecuritySAML20AssertionTokenSecurityHandler extends AbstractMessa
.get(SAML2AssertionValidationParameters.CONFIRMED_SUBJECT_CONFIRMATION));
break;
case INVALID:
- log.warn("Assertion token validation was INVALID. Reason: {}", validationMsg);
+ log.warn("Assertion token validation was INVALID. Reason(s): {}",
+ validationContext.getValidationFailureMessages());
if (isInvalidFatal()) {
SOAPMessagingSupport.registerSOAP11Fault(messageContext,
WSSecurityConstants.SOAP_FAULT_INVALID_SECURITY_TOKEN,
@@ -316,7 +310,8 @@ public class WSSecuritySAML20AssertionTokenSecurityHandler extends AbstractMessa
.get(SAML2AssertionValidationParameters.CONFIRMED_SUBJECT_CONFIRMATION));
break;
case INDETERMINATE:
- log.warn("Assertion token validation was INDETERMINATE. Reason: {}", validationMsg);
+ log.warn("Assertion token validation was INDETERMINATE. Reason(s): {}",
+ validationContext.getValidationFailureMessages());
if (isInvalidFatal()) {
SOAPMessagingSupport.registerSOAP11Fault(messageContext,
WSSecurityConstants.SOAP_FAULT_INVALID_SECURITY_TOKEN,
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/tests/MockAssertionValidator.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/tests/MockAssertionValidator.java
index 0c511481c..136c8dd20 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/tests/MockAssertionValidator.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/tests/MockAssertionValidator.java
@@ -67,7 +67,7 @@ public class MockAssertionValidator extends SAML20AssertionValidator {
if (ValidationResult.class.isInstance(result)) {
ValidationResult vr = ValidationResult.class.cast(result);
if (!ValidationResult.VALID.equals(vr)) {
- context.setValidationFailureMessage("Mock validation was not valid");
+ context.getValidationFailureMessages().add("Mock validation was not valid");
}
return vr;
}
@@ -75,7 +75,7 @@ public class MockAssertionValidator extends SAML20AssertionValidator {
if (Pair.class.isInstance(result)) {
Pair<ValidationResult,String> pair = Pair.class.cast(result);
if (!ValidationResult.VALID.equals(pair.getFirst())) {
- context.setValidationFailureMessage(pair.getSecond());
+ context.getValidationFailureMessages().add(pair.getSecond());
}
return Constraint.isNotNull(pair.getFirst(), "ValidationResult was null");
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list