Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ versions.springBootVersion = "3.5.13"
versions.guavaVersion = "33.5.0-jre"
versions.seleniumVersion = "4.43.0"
versions.braveVersion = "6.3.1"
versions.opensaml = "4.0.1"
versions.opensaml = "4.3.2"

// 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
Expand Up @@ -4,16 +4,30 @@
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneProvisioning;
import org.opensaml.core.config.ConfigurationService;
import org.opensaml.core.config.InitializationException;
import org.opensaml.core.config.Initializer;
import org.opensaml.security.config.GlobalNamedCurveRegistryInitializer;
import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.security.saml2.Saml2Exception;
import org.springframework.security.saml2.core.OpenSamlInitializationService;

import java.security.Security;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.concurrent.atomic.AtomicBoolean;

import static org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap.CONFIG_PROPERTY_ECDH_DEFAULT_KDF;

@Configuration
@Slf4j
public class IdentityZoneConfig {

private static final AtomicBoolean samlInitialized = new AtomicBoolean(false);

@Bean
public BouncyCastleFipsProvider setUpBouncyCastle() {
// Ensure non blocking random if system property java.security.egd is set
Expand Down Expand Up @@ -48,4 +62,28 @@ public IdentityZoneHolder.Initializer identityZoneHolderInitializer(IdentityZone

return new IdentityZoneHolder.Initializer(provisioning, samlKeyManagerFactory);
}

@Bean
public static Boolean setupOpenSaml() {
if (samlInitialized.compareAndSet(false, true)) {
Properties props = ConfigurationService.getConfigurationProperties();
props.put(CONFIG_PROPERTY_ECDH_DEFAULT_KDF, DefaultSecurityConfigurationBootstrap.PBKDF2);
Class<?> toSkip = GlobalNamedCurveRegistryInitializer.class;
ServiceLoader.load(Initializer.class).stream().filter((provider) -> provider.type() != toSkip).forEach((provider) -> init(provider));
try {
OpenSamlInitializationService.initialize();
} catch (NoClassDefFoundError | NoSuchMethodError e) {
// ignore
}
}
return Boolean.TRUE;
}

private static void init(ServiceLoader.Provider<Initializer> provider) {
try {
provider.get().init();
} catch (InitializationException ex) {
throw new Saml2Exception(ex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.saml2.Saml2Exception;
import org.springframework.security.saml2.core.OpenSamlInitializationService;
import org.springframework.security.saml2.core.Saml2Error;
import org.springframework.security.saml2.core.Saml2ErrorCodes;
import org.springframework.security.saml2.core.Saml2ResponseValidatorResult;
Expand Down Expand Up @@ -113,7 +112,7 @@
public final class OpenSaml4AuthenticationProvider implements AuthenticationProvider, ZoneAware {

static {
OpenSamlInitializationService.initialize();
IdentityZoneConfig.setupOpenSaml();
}

private final Log logger = LogFactory.getLog(this.getClass());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.saml2.Saml2Exception;
import org.springframework.security.saml2.core.OpenSamlInitializationService;
import org.springframework.security.saml2.core.Saml2Error;
import org.springframework.security.saml2.core.Saml2ErrorCodes;
import org.springframework.security.saml2.core.Saml2ResponseValidatorResult;
Expand Down Expand Up @@ -73,7 +72,7 @@
public final class Saml2BearerGrantAuthenticationConverter implements AuthenticationConverter {

static {
OpenSamlInitializationService.initialize();
IdentityZoneConfig.setupOpenSaml();
}

private static final AssertionUnmarshaller assertionUnmarshaller;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

@Slf4j
@EnableConfigurationProperties({SamlConfigProps.class})
@DependsOn({"setUpBouncyCastle", "setupOpenSaml"})
@Configuration
@Data
public class SamlConfiguration {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
import org.springframework.security.saml2.provider.service.registration.InMemoryRelyingPartyRegistrationRepository;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistrationRepository;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static org.cloudfoundry.identity.uaa.provider.saml.SamlMetadataEndpoint.DEFAULT_REGISTRATION_ID;

@DependsOn({"setUpBouncyCastle", "setupOpenSaml"})
@Configuration
@Slf4j
public class SamlRelyingPartyRegistrationRepositoryConfig {
Expand All @@ -44,7 +44,6 @@ public SamlRelyingPartyRegistrationRepositoryConfig(@Qualifier("samlEntityID") S
this.signatureAlgorithms = signatureAlgorithms;
}

@DependsOn({"setUpBouncyCastle"})
@Bean
RelyingPartyRegistrationRepository relyingPartyRegistrationRepository(SamlIdentityProviderConfigurator samlIdentityProviderConfigurator) {
SamlKeyManagerFactory.SamlConfigPropsSamlKeyManagerImpl samlKeyManager = new SamlKeyManagerFactory.SamlConfigPropsSamlKeyManagerImpl(samlConfigProps);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ public class BootstrapSamlIdentityProviderDataTests {

@BeforeEach
void beforeEach() {
IdentityZoneConfig.setupOpenSaml();
bootstrap = new BootstrapSamlIdentityProviderData(new SamlIdentityProviderConfigurator(mock(JdbcIdentityProviderProvisioning.class), new IdentityZoneManagerImpl(), mock(FixedHttpMetaDataProvider.class)));
singleAdd = new SamlIdentityProviderDefinition()
.setMetaDataLocation(BootstrapSamlIdentityProviderDataTests.XML_WITHOUT_ID.formatted(new RandomValueStringGenerator().generate()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
import org.junit.jupiter.params.provider.NullSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.opensaml.core.config.InitializationException;
import org.opensaml.core.config.InitializationService;
import org.opensaml.saml.saml2.core.AuthnContext;
import org.opensaml.saml.saml2.core.Response;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -183,7 +182,7 @@ void configureProvider() throws SecurityException, SQLException, InitializationE
RequestContextHolder.setRequestAttributes(servletWebRequest);
DbUtils dbUtils = new DbUtils();

InitializationService.initialize();
IdentityZoneConfig.setupOpenSaml();

ScimGroupProvisioning groupProvisioning = new JdbcScimGroupProvisioning(
namedJdbcTemplate, new JdbcPagingListFactory(namedJdbcTemplate, limitSqlAdapter),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.cloudfoundry.identity.uaa.zone.IdentityZone;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport;
Expand Down Expand Up @@ -93,6 +94,11 @@ class OpenSaml4AuthenticationProviderUnitTests {

private final OpenSaml4AuthenticationProvider provider = new OpenSaml4AuthenticationProvider();

@BeforeEach
void setUp() {
IdentityZoneConfig.setupOpenSaml();
}

@AfterEach void cleanup() {
IdentityZoneHolder.clear();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@
import org.opensaml.saml.saml2.core.AttributeValue;
import org.w3c.dom.Element;

import org.springframework.security.saml2.core.OpenSamlInitializationService;

/**
* This was copied from Spring Security Test Classes
* <p/>
Expand All @@ -51,7 +49,7 @@
public final class TestCustomOpenSamlObjects {

static {
OpenSamlInitializationService.initialize();
IdentityZoneConfig.setupOpenSaml();
XMLObjectProviderRegistrySupport.getMarshallerFactory()
.registerMarshaller(CustomOpenSamlObject.TYPE_NAME,
new TestCustomOpenSamlObjects.CustomSamlObjectMarshaller());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@
import org.opensaml.xmlsec.signature.support.SignatureException;
import org.opensaml.xmlsec.signature.support.SignatureSupport;
import org.springframework.security.saml2.Saml2Exception;
import org.springframework.security.saml2.core.OpenSamlInitializationService;
import org.springframework.security.saml2.core.Saml2X509Credential;
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration;

Expand Down Expand Up @@ -101,7 +100,7 @@ public final class TestOpenSamlObjects {
public static final String RELYING_PARTY_ENTITY_ID = "https://localhost/saml2/service-provider-metadata/idp-alias";

static {
OpenSamlInitializationService.initialize();
IdentityZoneConfig.setupOpenSaml();
}

private TestOpenSamlObjects() {
Expand Down Expand Up @@ -133,6 +132,7 @@ static Response signedResponseWithOneAssertion() {

static Response signedResponseWithOneAssertion(Consumer<Response> responseConsumer) {
Response response = response();
response.setIssueInstant(Instant.now());
response.getAssertions().add(assertion());
responseConsumer.accept(response);
return signed(response, TestSaml2X509Credentials.assertingPartySigningCredential(), RELYING_PARTY_ENTITY_ID);
Expand All @@ -156,6 +156,7 @@ public static Assertion assertion(String username, String issuerEntityId, String
Assertion assertion = build(Assertion.DEFAULT_ELEMENT_NAME);
assertion.setID("A" + UUID.randomUUID());
assertion.setVersion(SAMLVersion.VERSION_20);
assertion.setIssueInstant(Instant.now());
assertion.setIssuer(issuer(issuerEntityId));
assertion.setSubject(subject(username));
assertion.setConditions(conditions());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.cloudfoundry.identity.uaa.db.beans.JdbcUrlCustomizer;
import org.cloudfoundry.identity.uaa.extensions.PollutionPreventionExtension;
import org.cloudfoundry.identity.uaa.impl.config.YamlServletProfileInitializer;
import org.cloudfoundry.identity.uaa.provider.saml.IdentityZoneConfig;
import org.cloudfoundry.identity.uaa.test.TestClient;
import org.cloudfoundry.identity.uaa.zone.ZoneContextPathSessionFilter;
import org.cloudfoundry.identity.uaa.zone.ZonePathContextRewritingFilter;
Expand Down Expand Up @@ -71,6 +72,7 @@ class TestPropertyInitializer implements ApplicationContextInitializer<Configura
@Override
public void initialize(ConfigurableWebApplicationContext applicationContext) {
System.setProperty("UAA_CONFIG_URL","classpath:integration_test_properties.yml");
IdentityZoneConfig.setupOpenSaml();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.cloudfoundry.identity.uaa.impl.config.YamlConfigurationValidator;
import org.cloudfoundry.identity.uaa.impl.config.YamlServletProfileInitializer;
import org.cloudfoundry.identity.uaa.provider.saml.IdentityZoneConfig;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeansException;
Expand Down Expand Up @@ -48,6 +49,7 @@ void invalidConfiguration() {
}

private static TestApplicationContext createApplicationContext() {
IdentityZoneConfig.setupOpenSaml();
var applicationContext = new TestApplicationContext();
var servletContext = new TestMockContext();
applicationContext.setServletContext(servletContext);
Expand Down
Loading