Skip to content
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ subprojects {
resolutionStrategy.eachDependency { DependencyResolveDetails details ->
if (details.requested.group == 'org.opensaml' && details.requested.name.startsWith("opensaml-")) {
details.useVersion "${versions.opensaml}"
details.because 'Spring Security 5.8.x allows OpenSAML 3 or 4. OpenSAML 3 has reached its end-of-life. Spring Security 6 drops support for 3, using 4.'
details.because 'Pinning all opensaml modules to the same version for OpenSAML 5 migration.'
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ versions.springBootVersion = "3.5.13"
versions.guavaVersion = "33.6.0-jre"
versions.seleniumVersion = "4.43.0"
versions.braveVersion = "6.3.1"
versions.opensaml = "4.3.2"
// OpenSAML 5.2.x pulls non-FIPS classes; stay on 5.1.x until resolved
versions.opensaml = "5.1.6"

// Versions we're overriding from the Spring Boot Bom (Dependabot does not issue PRs to bump these versions, so we need to manually bump them)
ext["selenium.version"] = "${versions.seleniumVersion}" // Selenium for integration tests only
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.cloudfoundry.identity.uaa.authentication;

import org.springframework.security.saml2.core.Saml2Error;
import org.springframework.security.saml2.provider.service.authentication.logout.OpenSamlLogoutRequestValidator;
import org.springframework.security.saml2.provider.service.authentication.logout.OpenSaml5LogoutRequestValidator;
import org.springframework.security.saml2.provider.service.authentication.logout.Saml2LogoutRequestValidator;
Comment thread
strehle marked this conversation as resolved.
import org.springframework.security.saml2.provider.service.authentication.logout.Saml2LogoutRequestValidatorParameters;
import org.springframework.security.saml2.provider.service.authentication.logout.Saml2LogoutValidatorResult;
Expand All @@ -17,7 +17,7 @@ public class SamlLogoutRequestValidator implements Saml2LogoutRequestValidator {
private final Saml2LogoutRequestValidator delegate;

public SamlLogoutRequestValidator() {
this.delegate = new OpenSamlLogoutRequestValidator();
this.delegate = new OpenSaml5LogoutRequestValidator();
}

public SamlLogoutRequestValidator(Saml2LogoutRequestValidator delegate) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package org.cloudfoundry.identity.uaa.authentication;

import org.springframework.security.saml2.core.Saml2Error;
import org.springframework.security.saml2.provider.service.authentication.logout.OpenSamlLogoutResponseValidator;
import org.springframework.security.saml2.provider.service.authentication.logout.OpenSaml5LogoutResponseValidator;
import org.springframework.security.saml2.provider.service.authentication.logout.Saml2LogoutResponseValidator;
Comment thread
strehle marked this conversation as resolved.
import org.springframework.security.saml2.provider.service.authentication.logout.Saml2LogoutResponseValidatorParameters;
import org.springframework.security.saml2.provider.service.authentication.logout.Saml2LogoutValidatorResult;
Expand All @@ -18,7 +18,7 @@ public class SamlLogoutResponseValidator implements Saml2LogoutResponseValidator
private final Saml2LogoutResponseValidator delegate;

public SamlLogoutResponseValidator() {
this.delegate = new OpenSamlLogoutResponseValidator();
this.delegate = new OpenSaml5LogoutResponseValidator();
}

public SamlLogoutResponseValidator(Saml2LogoutResponseValidator delegate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import jakarta.annotation.Nonnull;
import lombok.Getter;
import net.shibboleth.utilities.java.support.xml.ParserPool;
import net.shibboleth.shared.xml.ParserPool;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.cloudfoundry.identity.uaa.zone.IdentityZone;
Expand Down Expand Up @@ -103,13 +103,17 @@
import static org.cloudfoundry.identity.uaa.util.UaaUrlUtils.normalizeUrlForPortComparison;

/**
* This was copied from Spring Security, and modified to work with Open SAML 4.0.x
* The original class only works with Open SAML 4.1.x+
* This was originally copied from Spring Security, and modified to work with Open SAML 4.0.x,
* then further updated for Open SAML 5.x compatibility.
* <p/>
* Once we can move to the spring-security version of OpenSaml4AuthenticationProvider,
* this class should be removed, along with OpenSamlDecryptionUtils and OpenSamlVerificationUtils.
* Key changes from OpenSAML 4 to 5:
* - {@code net.shibboleth.utilities.java.support} packages moved to {@code net.shibboleth.shared}
* - {@code SAML20AssertionValidator} constructor gains a 4th {@code AssertionValidator} parameter
* - {@code ValidationContext.getValidationFailureMessage()} renamed to {@code getValidationFailureMessages()}
* - {@code ConditionValidator.validate()} now throws {@code AssertionValidationException}
* - {@code BearerSubjectConfirmationValidator.validateAddress()} removed (address validation dropped)
*/
public final class OpenSaml4AuthenticationProvider implements AuthenticationProvider, ZoneAware {
public final class OpenSaml5AuthenticationProvider implements AuthenticationProvider, ZoneAware {

static {
SamlConfiguration.setupOpenSaml();
Expand Down Expand Up @@ -144,9 +148,9 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
private Converter<ResponseToken, ? extends AbstractAuthenticationToken> responseAuthenticationConverter = createDefaultResponseAuthenticationConverter();

/**
* Creates an {@link OpenSaml4AuthenticationProvider}
* Creates an {@link OpenSaml5AuthenticationProvider}
*/
public OpenSaml4AuthenticationProvider() {
public OpenSaml5AuthenticationProvider() {
XMLObjectProviderRegistry registry = ConfigurationService.get(XMLObjectProviderRegistry.class);
this.responseUnmarshaller = (ResponseUnmarshaller) registry.getUnmarshallerFactory()
.getUnmarshaller(Response.DEFAULT_ELEMENT_NAME);
Expand All @@ -160,7 +164,7 @@ public OpenSaml4AuthenticationProvider() {
* {@link #createDefaultResponseValidator()}, like so:
*
* <pre>
* OpenSaml4AuthenticationProvider provider = new OpenSaml4AuthenticationProvider();
* OpenSaml5AuthenticationProvider provider = new OpenSaml5AuthenticationProvider();
* provider.setResponseValidator(responseToken -&gt; {
* Saml2ResponseValidatorResult result = createDefaultResponseValidator()
* .convert(responseToken)
Expand Down Expand Up @@ -574,7 +578,7 @@ private static Converter<AssertionToken, Saml2ResponseValidatorResult> createAss
}
String message = "Invalid assertion [%s] for SAML response [%s]: %s".formatted(assertion.getID(),
assertion.getParent() != null ? ((Response) assertion.getParent()).getID() : assertion.getID(),
context.getValidationFailureMessage());
String.join("; ", context.getValidationFailureMessages()));
return Saml2ResponseValidatorResult.failure(new Saml2Error(errorCode, message));
};
}
Expand All @@ -601,6 +605,8 @@ private static ValidationContext createValidationContext(AssertionToken assertio
params.put(SAML2AssertionValidationParameters.COND_VALID_AUDIENCES, Collections.singleton(audience));
params.put(SAML2AssertionValidationParameters.SC_VALID_RECIPIENTS, Collections.singleton(recipient));
params.put(SAML2AssertionValidationParameters.VALID_ISSUERS, Collections.singleton(assertingPartyEntityId));
// Disable address checking - we don't track valid client addresses
params.put(SAML2AssertionValidationParameters.SC_CHECK_ADDRESS, false);
paramsConsumer.accept(params);
return new ValidationContext(params);
}
Expand Down Expand Up @@ -681,18 +687,11 @@ public ValidationResult validate(Condition condition, Assertion assertion, Valid
}
});
conditions.add(new ProxyRestrictionConditionValidator());
subjects.add(new BearerSubjectConfirmationValidator() {
@Override
protected ValidationResult validateAddress(SubjectConfirmation confirmation, Assertion assertion,
ValidationContext context, boolean required) {
// applications should validate their own addresses - gh-7514
return ValidationResult.VALID;
}
});
subjects.add(new BearerSubjectConfirmationValidator());
}

private static final SAML20AssertionValidator attributeValidator = new SAML20AssertionValidator(conditions,
subjects, statements, null, null) {
subjects, statements, null, null, null) {
@Nonnull
@Override
protected ValidationResult validateSignature(Assertion token, ValidationContext context) {
Expand All @@ -701,7 +700,7 @@ protected ValidationResult validateSignature(Assertion token, ValidationContext
};

static SAML20AssertionValidator createSignatureValidator(SignatureTrustEngine engine) {
return new SAML20AssertionValidator(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), engine,
return new SAML20AssertionValidator(new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), null, engine,
validator) {
@Nonnull
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
import java.util.Collection;

/**
* This class was copied from Spring Security 5.6.0 to get the OpenSaml4AuthenticationProvider to work.
* It should be removed once we are able to more to the spring-security version of OpenSaml4AuthenticationProvider.
* This class was copied from Spring Security 5.6.0 to get the OpenSaml5AuthenticationProvider to work.
* It should be removed once we are able to move to the spring-security version of OpenSaml5AuthenticationProvider.
* <p/>
* Utility methods for decrypting SAML components with OpenSAML
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package org.cloudfoundry.identity.uaa.provider.saml;

import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
import net.shibboleth.shared.resolver.CriteriaSet;
import org.opensaml.core.criterion.EntityIdCriterion;
import org.opensaml.saml.common.xml.SAMLConstants;
import org.opensaml.saml.criterion.ProtocolCriterion;
Expand Down Expand Up @@ -48,8 +48,8 @@
import java.util.Set;

/**
* This class was copied from Spring Security 5.6.0 to get the OpenSaml4AuthenticationProvider to work.
* It should be removed once we are able to more to the spring-security version of OpenSaml4AuthenticationProvider.
* This class was copied from Spring Security 5.6.0 to get the OpenSaml5AuthenticationProvider to work.
* It should be removed once we are able to move to the spring-security version of OpenSaml5AuthenticationProvider.
* <p/>
* Utility methods for verifying SAML component signatures with OpenSAML
* <p>
Expand Down
Loading
Loading