[java-opensaml] branch main updated: OSJ-420 - SAML20AssertionValidator allows non-Entity Issuers
Scott Cantor
cantor.2 at osu.edu
Fri Oct 4 19:45:23 UTC 2024
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=5a991f8823403584ac93337280eed001987f2815
The following commit(s) were added to refs/heads/main by this push:
new 5a991f882 OSJ-420 - SAML20AssertionValidator allows non-Entity Issuers
5a991f882 is described below
commit 5a991f8823403584ac93337280eed001987f2815
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Fri Oct 4 15:45:20 2024 -0400
OSJ-420 - SAML20AssertionValidator allows non-Entity Issuers
https://shibboleth.atlassian.net/browse/OSJ-420
Added new boolean option to enforce issuer format.
---
.../saml2/assertion/SAML20AssertionValidator.java | 14 ++++++++++
.../SAML2AssertionValidationParameters.java | 9 ++++++
.../DefaultAssertionValidationContextBuilder.java | 32 ++++++++++++++++++++++
3 files changed, 55 insertions(+)
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 9c139465b..372ce8952 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
@@ -41,6 +41,7 @@ import org.opensaml.saml.saml2.core.Assertion;
import org.opensaml.saml.saml2.core.Condition;
import org.opensaml.saml.saml2.core.Conditions;
import org.opensaml.saml.saml2.core.Issuer;
+import org.opensaml.saml.saml2.core.NameIDType;
import org.opensaml.saml.saml2.core.Statement;
import org.opensaml.saml.saml2.core.Subject;
import org.opensaml.saml.saml2.core.SubjectConfirmation;
@@ -431,6 +432,7 @@ public class SAML20AssertionValidator {
return ValidationResult.VALID;
}
+// Checkstyle: CyclomaticComplexity OFF
/**
* Validates the Assertion {@link Issuer}.
*
@@ -455,6 +457,17 @@ public class SAML20AssertionValidator {
}
log.debug("Evaluating Assertion Issuer of : {}", issuer);
+
+ final Boolean requireEntityIssuer = (Boolean) context.getStaticParameters().get(
+ SAML2AssertionValidationParameters.REQUIRE_ENTITY_ISSUER);
+ if (requireEntityIssuer != null && requireEntityIssuer) {
+ assert issuerElement != null;
+ if (issuerElement.getFormat() != null && !NameIDType.ENTITY.equals(issuerElement.getFormat())) {
+ context.getValidationFailureMessages().add(
+ String.format("Issuer had invalid Format: %s", issuerElement.getFormat()));
+ return ValidationResult.INVALID;
+ }
+ }
final Set<String> validIssuers;
try {
@@ -484,6 +497,7 @@ public class SAML20AssertionValidator {
"Issuer of Assertion '%s' did not match any valid issuers", assertion.getID()));
return ValidationResult.INVALID;
}
+// Checkstyle: CyclomaticComplexity ON
/**
* Validates the signature of the assertion, if it is signed.
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 7bfcfa716..6d163d8f7 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
@@ -17,6 +17,7 @@ package org.opensaml.saml.saml2.assertion;
import javax.annotation.Nonnull;
import org.opensaml.saml.saml2.core.AuthnStatement;
+import org.opensaml.saml.saml2.core.NameIDType;
import org.opensaml.saml.saml2.core.SubjectLocality;
import net.shibboleth.shared.annotation.constraint.NotEmpty;
@@ -62,6 +63,14 @@ public final class SAML2AssertionValidationParameters {
*/
@Nonnull @NotEmpty public static final String VALID_ISSUERS = STD_PREFIX + ".ValidIssuers";
+ /**
+ * Carries a {@link java.lang.Boolean} flag which indicates whether the issuer must have the
+ * {@link NameIDType#ENTITY} Format.
+ *
+ * @since 5.2.0
+ */
+ @Nonnull @NotEmpty public static final String REQUIRE_ENTITY_ISSUER = STD_PREFIX + ".RequireEntityIssuer";
+
/**
* Carries a {@link java.lang.Boolean} flag which indicates whether the Assertion is required to be signed.
*/
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 9b7564442..f0ca65130 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
@@ -55,6 +55,7 @@ import org.opensaml.saml.criterion.RoleDescriptorCriterion;
import org.opensaml.saml.saml2.assertion.SAML2AssertionValidationParameters;
import org.opensaml.saml.saml2.core.Assertion;
import org.opensaml.saml.saml2.core.Issuer;
+import org.opensaml.saml.saml2.core.NameIDType;
import org.opensaml.saml.saml2.metadata.RoleDescriptor;
import org.opensaml.saml.saml2.profile.impl.ValidateAssertions.AssertionValidationInput;
import org.opensaml.security.SecurityException;
@@ -118,6 +119,9 @@ public class DefaultAssertionValidationContextBuilder
/** Function for determining additional valid Issuer values. */
@Nonnull private Function<ProfileRequestContext, Set<String>> validIssuers;
+ /** Predicate for determining whether to require issuer be of the {@link NameIDType#ENTITY} format. */
+ @Nonnull private Predicate<ProfileRequestContext> requireEntityIssuer;
+
/** Function for determining the valid InResponseTo value. */
@Nullable private Function<ProfileRequestContext, String> inResponseTo;
@@ -157,6 +161,7 @@ public class DefaultAssertionValidationContextBuilder
addressRequired = PredicateSupport.alwaysFalse();
requiredConditions = CollectionSupport.emptySet();
validIssuers = new DefaultValidIssuersLookupFunction();
+ requireEntityIssuer = PredicateSupport.alwaysFalse();
securityParametersLookupStrategy = new ChildContextLookup<>(SecurityParametersContext.class)
.compose(new InboundMessageContextLookup());
@@ -557,6 +562,30 @@ public class DefaultAssertionValidationContextBuilder
public void setValidIssuers(@Nonnull final Function<ProfileRequestContext,Set<String>> function) {
validIssuers = Constraint.isNotNull(function, "Valied Issuers function was null");
}
+
+ /**
+ * Get the predicate which determines whether to require the Issuer contain the {@link NameIDType#ENTITY} Format.
+ *
+ * @return predicate
+ *
+ * @since 5.2.0
+ */
+ @Nonnull public Predicate<ProfileRequestContext> getRequireEntityIssuer() {
+ return requireEntityIssuer;
+ }
+
+ /**
+ * Get the predicate which determines whether to require the Issuer contain the {@link NameIDType#ENTITY} Format.
+ *
+ * <p>Defaults to false.</p>
+ *
+ * @param predicate the condition to set
+ *
+ * @since 5.2.0
+ */
+ public void setRequireEntityIssuer(@Nonnull final Predicate<ProfileRequestContext> predicate) {
+ requireEntityIssuer = Constraint.isNotNull(predicate, "Entity issuer predicate was null");
+ }
/**
* Get the function for determining the max allowed time since authentication.
@@ -650,6 +679,9 @@ public class DefaultAssertionValidationContextBuilder
staticParams.put(SAML2AssertionValidationParameters.VALID_ISSUERS,
getValidIssuers().apply(input.getProfileRequestContext()));
+ staticParams.put(SAML2AssertionValidationParameters.REQUIRE_ENTITY_ISSUER,
+ Boolean.valueOf(getRequireEntityIssuer().test(input.getProfileRequestContext())));
+
// Signature
populateSignatureParameters(staticParams, input);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the commits
mailing list