[java-opensaml] 02/06: Enhance SAML 2 assertion validator to resolve beans from context.

Brent Putman putmanb at georgetown.edu
Fri Jan 24 23:06:07 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=6238a13269bf9b103fafbdd094bf31d8dd5c4fa6

commit 6238a13269bf9b103fafbdd094bf31d8dd5c4fa6
Author: Brent Putman <putmanb at georgetown.edu>
AuthorDate: Tue Dec 17 17:21:17 2019 -0500

    Enhance SAML 2 assertion validator to resolve beans from context.
    
    Allows to dynamically pass SignatureTrustEngine and
    SignaturePrevalidator in the ValidationContext, which take precedence
    over what is statically wired on the validator.
---
 .../saml2/assertion/SAML20AssertionValidator.java  | 73 +++++++++++++++++++---
 .../SAML2AssertionValidationParameters.java        | 13 ++++
 .../assertion/SAML20AssertionValidatorTest.java    | 42 +++++++++++++
 3 files changed, 120 insertions(+), 8 deletions(-)

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 aeae816..815f68b 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
@@ -80,6 +80,16 @@ import org.w3c.dom.Element;
  * with the above values.
  * </li>
  * <li>
+ * {@link SAML2AssertionValidationParameters#SIGNATURE_VALIDATION_TRUST_ENGINE}:
+ * Optional.
+ * If not supplied, defaults to the locally-injected instance.
+ * </li>
+ * <li>
+ * {@link SAML2AssertionValidationParameters#SIGNATURE_VALIDATION_PREVALIDATOR}:
+ * Optional.
+ * If not supplied, defaults to the locally-injected instance.
+ * </li>
+ * <li>
  * {@link SAML2AssertionValidationParameters#CLOCK_SKEW}:
  * Optional.
  * If not present the default clock skew of {@link SAML20AssertionValidator#DEFAULT_CLOCK_SKEW} 
@@ -313,12 +323,6 @@ public class SAML20AssertionValidator {
             return ValidationResult.VALID;
         }
         
-        if (trustEngine == 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");
-            return ValidationResult.INDETERMINATE;
-        }
-        
         return performSignatureValidation(token, context);
     }
     
@@ -334,6 +338,14 @@ public class SAML20AssertionValidator {
      */
     @Nonnull protected ValidationResult performSignatureValidation(@Nonnull final Assertion token, 
             @Nonnull final ValidationContext context) throws AssertionValidationException {
+
+        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");
+            return ValidationResult.INDETERMINATE;
+        }
+
         final Signature signature = token.getSignature();
         
         String tokenIssuer = null;
@@ -345,7 +357,12 @@ public class SAML20AssertionValidator {
                 token.getID(), tokenIssuer);
         
         try {
-            signaturePrevalidator.validate(signature);
+            final SignaturePrevalidator prevalidator = getSignatureValidationPrevalidator(token, context);
+            if (prevalidator != null) {
+                prevalidator.validate(signature);
+            } else {
+                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);
@@ -356,7 +373,7 @@ public class SAML20AssertionValidator {
         final CriteriaSet criteriaSet = getSignatureValidationCriteriaSet(token, context);
         
         try {
-            if (trustEngine.validate(signature, criteriaSet)) {
+            if (signatureTrustEngine.validate(signature, criteriaSet)) {
                 log.debug("Validation of signature of Assertion '{}' from Issuer '{}' was successful",
                         token.getID(), tokenIssuer);
                 return ValidationResult.VALID;
@@ -378,6 +395,46 @@ public class SAML20AssertionValidator {
     }
 
     /**
+     * Get the signature trust engine that will be used in evaluating the Assertion signature.
+     *
+     * @param token assertion whose signature will be validated
+     * @param context current validation context
+     * @return the criteria set to use
+     */
+    @Nonnull protected SignatureTrustEngine getSignatureValidationTrustEngine(@Nonnull final Assertion token,
+            @Nonnull final ValidationContext context) {
+
+        final SignatureTrustEngine contextEngine = (SignatureTrustEngine) context.getStaticParameters()
+               .get(SAML2AssertionValidationParameters.SIGNATURE_VALIDATION_TRUST_ENGINE);
+
+        if (contextEngine != null) {
+            return contextEngine;
+        }
+
+        return trustEngine;
+    }
+
+    /**
+     * Get the signature trust engine that will be used in evaluating the Assertion signature.
+     *
+     * @param token assertion whose signature will be validated
+     * @param context current validation context
+     * @return the criteria set to use
+     */
+    @Nonnull protected SignaturePrevalidator getSignatureValidationPrevalidator(@Nonnull final Assertion token,
+            @Nonnull final ValidationContext context) {
+
+        final SignaturePrevalidator contextPrevalidator = (SignaturePrevalidator) context.getStaticParameters()
+               .get(SAML2AssertionValidationParameters.SIGNATURE_VALIDATION_PREVALIDATOR);
+
+        if (contextPrevalidator != null) {
+            return contextPrevalidator;
+        }
+
+       return signaturePrevalidator;
+    }
+
+    /**
      * Get the criteria set that will be used in evaluating the Assertion signature via the supplied trust engine.
      * 
      * @param token assertion whose signature will be validated
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 bcd3e97..c346d6c 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
@@ -57,6 +57,19 @@ public final class SAML2AssertionValidationParameters {
     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.
+     */
+    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.
+     * 
+     */
+    public static final String SIGNATURE_VALIDATION_PREVALIDATOR = STD_PREFIX + ".SignatureValidationPrevalidator";
+
+    /**
      * 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.
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/SAML20AssertionValidatorTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/SAML20AssertionValidatorTest.java
index 42a0850..987904a 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/SAML20AssertionValidatorTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/saml2/assertion/SAML20AssertionValidatorTest.java
@@ -223,6 +223,48 @@ public class SAML20AssertionValidatorTest extends BaseAssertionValidationTest {
     }
     
     @Test
+    public void testWithTrustedSignatureAndContextTrustEngine() throws AssertionValidationException, SecurityException, MarshallingException, SignatureException {
+        trustedCredentials.add(cred1);
+        signAssertion(getAssertion(), cred1);
+        
+        validator = new SAML20AssertionValidator(conditionValidators, subjectConfirmationValidators, statementValidators, null, signaturePrevalidator);
+        
+        Map<String,Object> staticParams = buildBasicStaticParameters();
+        staticParams.put(SAML2AssertionValidationParameters.SIGNATURE_REQUIRED, true);
+        staticParams.put(SAML2AssertionValidationParameters.SIGNATURE_VALIDATION_TRUST_ENGINE, signatureTrustEngine);
+        
+        ValidationContext validationContext = new ValidationContext(staticParams);
+        
+        Assertion assertion = getAssertion();
+        
+        Assert.assertEquals(validator.validate(assertion, validationContext), ValidationResult.VALID);
+        
+        Assert.assertSame(validationContext.getDynamicParameters().get(SAML2AssertionValidationParameters.CONFIRMED_SUBJECT_CONFIRMATION),
+                assertion.getSubject().getSubjectConfirmations().get(0));
+    }
+    
+    @Test
+    public void testWithTrustedSignatureAndContextPrevalidator() throws AssertionValidationException, SecurityException, MarshallingException, SignatureException {
+        trustedCredentials.add(cred1);
+        signAssertion(getAssertion(), cred1);
+        
+        validator = new SAML20AssertionValidator(conditionValidators, subjectConfirmationValidators, statementValidators, signatureTrustEngine, null);
+        
+        Map<String,Object> staticParams = buildBasicStaticParameters();
+        staticParams.put(SAML2AssertionValidationParameters.SIGNATURE_REQUIRED, true);
+        staticParams.put(SAML2AssertionValidationParameters.SIGNATURE_VALIDATION_PREVALIDATOR, signaturePrevalidator);
+        
+        ValidationContext validationContext = new ValidationContext(staticParams);
+        
+        Assertion assertion = getAssertion();
+        
+        Assert.assertEquals(validator.validate(assertion, validationContext), ValidationResult.VALID);
+        
+        Assert.assertSame(validationContext.getDynamicParameters().get(SAML2AssertionValidationParameters.CONFIRMED_SUBJECT_CONFIRMATION),
+                assertion.getSubject().getSubjectConfirmations().get(0));
+    }
+    
+    @Test
     public void testWithSignatureAndUntrustedCredential() throws AssertionValidationException, SecurityException, MarshallingException, SignatureException {
         trustedCredentials.add(cred2);
         signAssertion(getAssertion(), cred1);

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list