diff --git a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java index 5fef242e0c..a9010b5a58 100644 --- a/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java +++ b/saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProvider.java @@ -432,10 +432,8 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv */ public static Converter createDefaultAssertionValidator() { - return createAssertionValidator(Saml2ErrorCodes.INVALID_ASSERTION, - (assertionToken) -> SAML20AssertionValidators.attributeValidator, - (assertionToken) -> createValidationContext(assertionToken, - (params) -> params.put(SAML2AssertionValidationParameters.CLOCK_SKEW, Duration.ofMinutes(5)))); + return createDefaultAssertionValidatorWithParameters( + (params) -> params.put(SAML2AssertionValidationParameters.CLOCK_SKEW, Duration.ofMinutes(5))); } /** @@ -444,7 +442,9 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv * @param contextConverter the conversion strategy to use to generate a * {@link ValidationContext} for each assertion being validated * @return the default assertion validator strategy + * @deprecated Use {@link #createDefaultAssertionValidatorWithParameters} instead */ + @Deprecated public static Converter createDefaultAssertionValidator( Converter contextConverter) { @@ -452,6 +452,21 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv (assertionToken) -> SAML20AssertionValidators.attributeValidator, contextConverter); } + /** + * Construct a default strategy for validating each SAML 2.0 Assertion and associated + * {@link Authentication} token + * @param validationContextParameters a consumer for editing the values passed to the + * {@link ValidationContext} for each assertion being validated + * @return the default assertion validator strategy + * @since 5.8 + */ + public static Converter createDefaultAssertionValidatorWithParameters( + Consumer> validationContextParameters) { + return createAssertionValidator(Saml2ErrorCodes.INVALID_ASSERTION, + (assertionToken) -> SAML20AssertionValidators.attributeValidator, + (assertionToken) -> createValidationContext(assertionToken, validationContextParameters)); + } + /** * Construct a default strategy for converting a SAML 2.0 Response and * {@link Authentication} token into a {@link Saml2Authentication} diff --git a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java index 670c01a8e9..e4023a7be4 100644 --- a/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java +++ b/saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/authentication/OpenSaml4AuthenticationProviderTests.java @@ -520,6 +520,25 @@ public class OpenSaml4AuthenticationProviderTests { // @formatter:on } + // gh-11675 + @Test + public void authenticateWhenUsingCustomAssertionValidatorThenUses() { + OpenSaml4AuthenticationProvider provider = new OpenSaml4AuthenticationProvider(); + Consumer> validationParameters = mock(Consumer.class); + // @formatter:off + provider.setAssertionValidator(OpenSaml4AuthenticationProvider + .createDefaultAssertionValidatorWithParameters(validationParameters)); + // @formatter:on + Response response = response(); + Assertion assertion = assertion(); + OneTimeUse oneTimeUse = build(OneTimeUse.DEFAULT_ELEMENT_NAME); + assertion.getConditions().getConditions().add(oneTimeUse); + response.getAssertions().add(assertion); + Saml2AuthenticationToken token = token(signed(response), verifying(registration())); + provider.authenticate(token); + verify(validationParameters).accept(any()); + } + @Test public void authenticateWhenCustomAssertionValidatorThenUses() { Converter validator = mock(