From 006f58d11e480c5739fa3e0ef229a5f88aea3f57 Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Fri, 21 Aug 2020 12:02:14 -0600 Subject: [PATCH 1/2] Configure SAML 2.0 Service Provider via Metadata Closes gh-22986 --- .../saml2/Saml2RelyingPartyProperties.java | 13 ++++ ...RelyingPartyRegistrationConfiguration.java | 31 ++++++--- ...ml2RelyingPartyAutoConfigurationTests.java | 65 +++++++++++++++++++ .../Saml2RelyingPartyPropertiesTests.java | 8 +++ 4 files changed, 109 insertions(+), 8 deletions(-) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java index aa957dc4e550..3525b21cc02a 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java @@ -140,6 +140,11 @@ public static class Identityprovider { */ private String entityId; + /** + * Endpoint for discovery-based configuration. + */ + private String metadataUrl; + private final Singlesignon singlesignon = new Singlesignon(); private final Verification verification = new Verification(); @@ -152,6 +157,14 @@ public void setEntityId(String entityId) { this.entityId = entityId; } + public String getMetadataUrl() { + return this.metadataUrl; + } + + public void setMetadataUrl(String metadataUrl) { + this.metadataUrl = metadataUrl; + } + @Deprecated @DeprecatedConfigurationProperty(reason = "moved to 'singlesignon.url'") public String getSsoUrl() { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java index 327bdd4dd05d..148c691ae043 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java @@ -28,6 +28,7 @@ import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Identityprovider.Verification; import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Registration; import org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyProperties.Registration.Signing; +import org.springframework.boot.context.properties.PropertyMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -37,8 +38,10 @@ 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.security.saml2.provider.service.registration.RelyingPartyRegistrations; import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; /** * {@link Configuration @Configuration} used to map {@link Saml2RelyingPartyProperties} to @@ -64,16 +67,25 @@ private RelyingPartyRegistration asRegistration(Map.Entry } private RelyingPartyRegistration asRegistration(String id, Registration properties) { - boolean signRequest = properties.getIdentityprovider().getSinglesignon().isSignRequest(); - validateSigningCredentials(properties, signRequest); - RelyingPartyRegistration.Builder builder = RelyingPartyRegistration.withRegistrationId(id); + RelyingPartyRegistration.Builder builder; + boolean usingMetadata = StringUtils.hasText(properties.getIdentityprovider().getMetadataUrl()); + if (usingMetadata) { + builder = RelyingPartyRegistrations.fromMetadataLocation(properties.getIdentityprovider().getMetadataUrl()) + .registrationId(id); + } + else { + builder = RelyingPartyRegistration.withRegistrationId(id); + } builder.assertionConsumerServiceLocation( "{baseUrl}" + Saml2WebSsoAuthenticationFilter.DEFAULT_FILTER_PROCESSES_URI); + Saml2RelyingPartyProperties.Identityprovider identityprovider = properties.getIdentityprovider(); + PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull(); builder.assertingPartyDetails((details) -> { - details.singleSignOnServiceLocation(properties.getIdentityprovider().getSinglesignon().getUrl()); - details.entityId(properties.getIdentityprovider().getEntityId()); - details.singleSignOnServiceBinding(properties.getIdentityprovider().getSinglesignon().getBinding()); - details.wantAuthnRequestsSigned(signRequest); + map.from(identityprovider::getEntityId).to(details::entityId); + map.from(identityprovider.getSinglesignon()::getBinding).to(details::singleSignOnServiceBinding); + map.from(identityprovider.getSinglesignon()::getUrl).to(details::singleSignOnServiceLocation); + map.from(identityprovider.getSinglesignon()::isSignRequest).when((signRequest) -> !usingMetadata) + .to(details::wantAuthnRequestsSigned); }); builder.signingX509Credentials((credentials) -> properties.getSigning().getCredentials().stream() .map(this::asSigningCredential).forEach(credentials::add)); @@ -81,7 +93,10 @@ private RelyingPartyRegistration asRegistration(String id, Registration properti .verificationX509Credentials((credentials) -> properties.getIdentityprovider().getVerification() .getCredentials().stream().map(this::asVerificationCredential).forEach(credentials::add))); builder.entityId(properties.getRelyingPartyEntityId()); - return builder.build(); + RelyingPartyRegistration registration = builder.build(); + boolean signRequest = registration.getAssertingPartyDetails().getWantAuthnRequestsSigned(); + validateSigningCredentials(properties, signRequest); + return registration; } private void validateSigningCredentials(Registration properties, boolean signRequest) { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java index 7557912d4805..23a07f618fb3 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java @@ -20,6 +20,9 @@ import javax.servlet.Filter; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -55,6 +58,15 @@ class Saml2RelyingPartyAutoConfigurationTests { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner().withConfiguration( AutoConfigurations.of(Saml2RelyingPartyAutoConfiguration.class, SecurityAutoConfiguration.class)); + private MockWebServer server; + + @AfterEach + void cleanup() throws Exception { + if (this.server != null) { + this.server.shutdown(); + } + } + @Test void autoConfigurationShouldBeConditionalOnRelyingPartyRegistrationRepositoryClass() { this.contextRunner.withPropertyValues(getPropertyValues()).withClassLoader(new FilteredClassLoader( @@ -112,6 +124,19 @@ void autoConfigurationWhenSignRequestsFalseAndNoSigningCredentialsShouldNotThrow .run((context) -> assertThat(context).hasSingleBean(RelyingPartyRegistrationRepository.class)); } + @Test + void autoconfigurationShouldQueryIdentityProviderMetadataWhenMetadataUrlIsPresent() throws Exception { + this.server = new MockWebServer(); + this.server.start(); + String metadataUrl = this.server.url("").toString(); + setupMockResponse(); + this.contextRunner.withPropertyValues(PREFIX + ".foo.identityprovider.metadata-url=" + metadataUrl) + .run((context) -> { + assertThat(context).hasSingleBean(RelyingPartyRegistrationRepository.class); + assertThat(this.server.getRequestCount()).isEqualTo(1); + }); + } + @Test void relyingPartyRegistrationRepositoryShouldBeConditionalOnMissingBean() { this.contextRunner.withPropertyValues(getPropertyValues()) @@ -176,6 +201,46 @@ private boolean hasFilter(AssertableWebApplicationContext context, Class\n" + " \n" + + " \n" + + " \n" + " \n" + " \n" + + " \n" + + " MIIDZjCCAk6gAwIBAgIVAL9O+PA7SXtlwZZY8MVSE9On1cVWMA0GCSqGSIb3DQEB\n" + + " BQUAMCkxJzAlBgNVBAMTHmlkZW0tcHVwYWdlbnQuZG16LWludC51bmltby5pdDAe\n" + + " Fw0xMzA3MjQwMDQ0MTRaFw0zMzA3MjQwMDQ0MTRaMCkxJzAlBgNVBAMTHmlkZW0t\n" + + " cHVwYWdlbnQuZG16LWludC51bmltby5pdDCCASIwDQYJKoZIhvcNAMIIDQADggEP\n" + + " ADCCAQoCggEBAIAcp/VyzZGXUF99kwj4NvL/Rwv4YvBgLWzpCuoxqHZ/hmBwJtqS\n" + + " v0y9METBPFbgsF3hCISnxbcmNVxf/D0MoeKtw1YPbsUmow/bFe+r72hZ+IVAcejN\n" + + " iDJ7t5oTjsRN1t1SqvVVk6Ryk5AZhpFW+W9pE9N6c7kJ16Rp2/mbtax9OCzxpece\n" + + " byi1eiLfIBmkcRawL/vCc2v6VLI18i6HsNVO3l2yGosKCbuSoGDx2fCdAOk/rgdz\n" + + " cWOvFsIZSKuD+FVbSS/J9GVs7yotsS4PRl4iX9UMnfDnOMfO7bcBgbXtDl4SCU1v\n" + + " dJrRw7IL/pLz34Rv9a8nYitrzrxtLOp3nYUCAwEAAaOBhDCBgTBgBgMIIDEEWTBX\n" + + " gh5pZGVtLXB1cGFnZW50LmRtei1pbnQudW5pbW8uaXSGNWh0dHBzOi8vaWRlbS1w\n" + + " dXBhZ2VudC5kbXotaW50LnVuaW1vLml0L2lkcC9zaGliYm9sZXRoMB0GA1UdDgQW\n" + + " BBT8PANzz+adGnTRe8ldcyxAwe4VnzANBgkqhkiG9w0BAQUFAAOCAQEAOEnO8Clu\n" + + " 9z/Lf/8XOOsTdxJbV29DIF3G8KoQsB3dBsLwPZVEAQIP6ceS32Xaxrl6FMTDDNkL\n" + + " qUvvInUisw0+I5zZwYHybJQCletUWTnz58SC4C9G7FpuXHFZnOGtRcgGD1NOX4UU\n" + + " duus/4nVcGSLhDjszZ70Xtj0gw2Sn46oQPHTJ81QZ3Y9ih+Aj1c9OtUSBwtWZFkU\n" + + " yooAKoR8li68Yb21zN2N65AqV+ndL98M8xUYMKLONuAXStDeoVCipH6PJ09Z5U2p\n" + + " V5p4IQRV6QBsNw9CISJFuHzkVYTH5ZxzN80Ru46vh4y2M0Nu8GQ9I085KoZkrf5e\n" + + " Cq53OZt9ISjHEw==\n" + " \n" + + " \n" + " \n" + " \n" + " \n" + + " \n" + " \n" + " \n" + + " \n" + + " mailto:technical.contact@example.com\n" + + " \n" + " \n" + ""; + MockResponse mockResponse = new MockResponse().setBody(metadataResponse); + this.server.enqueue(mockResponse); + } + @Configuration(proxyBeanMethods = false) static class RegistrationRepositoryConfiguration { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java index 378a9a98407c..37d76e208b26 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java @@ -102,6 +102,14 @@ void customizeRelyingPartyEntityIdDefaultsToServiceProviderMetadata() { .isEqualTo(new Saml2RelyingPartyProperties.Registration().getRelyingPartyEntityId()); } + @Test + void customizeIdentityProviderMetadataUrl() { + bind("spring.security.saml2.relyingparty.registration.simplesamlphp.identityprovider.metadata-url", + "https://idp.example.org/metadata"); + assertThat(this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getMetadataUrl()) + .isEqualTo("https://idp.example.org/metadata"); + } + private void bind(String name, String value) { bind(Collections.singletonMap(name, value)); } From 3a6149a78919fe5c1bc0ecf34637bd8a1eaa52fc Mon Sep 17 00:00:00 2001 From: Josh Cummings Date: Tue, 1 Sep 2020 12:07:34 -0600 Subject: [PATCH 2/2] Incorporate PR Feedback --- .../saml2/Saml2RelyingPartyProperties.java | 10 +-- ...RelyingPartyRegistrationConfiguration.java | 4 +- ...ml2RelyingPartyAutoConfigurationTests.java | 76 +++++-------------- .../Saml2RelyingPartyPropertiesTests.java | 4 +- .../src/test/resources/saml/idp-metadata | 42 ++++++++++ 5 files changed, 70 insertions(+), 66 deletions(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/resources/saml/idp-metadata diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java index 3525b21cc02a..9f87dd42a533 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyProperties.java @@ -143,7 +143,7 @@ public static class Identityprovider { /** * Endpoint for discovery-based configuration. */ - private String metadataUrl; + private String metadataUri; private final Singlesignon singlesignon = new Singlesignon(); @@ -157,12 +157,12 @@ public void setEntityId(String entityId) { this.entityId = entityId; } - public String getMetadataUrl() { - return this.metadataUrl; + public String getMetadataUri() { + return this.metadataUri; } - public void setMetadataUrl(String metadataUrl) { - this.metadataUrl = metadataUrl; + public void setMetadataUri(String metadataUri) { + this.metadataUri = metadataUri; } @Deprecated diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java index 148c691ae043..747a0d928b8f 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyRegistrationConfiguration.java @@ -68,9 +68,9 @@ private RelyingPartyRegistration asRegistration(Map.Entry private RelyingPartyRegistration asRegistration(String id, Registration properties) { RelyingPartyRegistration.Builder builder; - boolean usingMetadata = StringUtils.hasText(properties.getIdentityprovider().getMetadataUrl()); + boolean usingMetadata = StringUtils.hasText(properties.getIdentityprovider().getMetadataUri()); if (usingMetadata) { - builder = RelyingPartyRegistrations.fromMetadataLocation(properties.getIdentityprovider().getMetadataUrl()) + builder = RelyingPartyRegistrations.fromMetadataLocation(properties.getIdentityprovider().getMetadataUri()) .registrationId(id); } else { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java index 23a07f618fb3..ccb9e1d94817 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyAutoConfigurationTests.java @@ -16,13 +16,14 @@ package org.springframework.boot.autoconfigure.security.saml2; +import java.io.InputStream; import java.util.List; import javax.servlet.Filter; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; -import org.junit.jupiter.api.AfterEach; +import okio.Buffer; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -33,6 +34,7 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; import org.springframework.security.config.BeanIds; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; @@ -58,15 +60,6 @@ class Saml2RelyingPartyAutoConfigurationTests { private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner().withConfiguration( AutoConfigurations.of(Saml2RelyingPartyAutoConfiguration.class, SecurityAutoConfiguration.class)); - private MockWebServer server; - - @AfterEach - void cleanup() throws Exception { - if (this.server != null) { - this.server.shutdown(); - } - } - @Test void autoConfigurationShouldBeConditionalOnRelyingPartyRegistrationRepositoryClass() { this.contextRunner.withPropertyValues(getPropertyValues()).withClassLoader(new FilteredClassLoader( @@ -126,15 +119,16 @@ void autoConfigurationWhenSignRequestsFalseAndNoSigningCredentialsShouldNotThrow @Test void autoconfigurationShouldQueryIdentityProviderMetadataWhenMetadataUrlIsPresent() throws Exception { - this.server = new MockWebServer(); - this.server.start(); - String metadataUrl = this.server.url("").toString(); - setupMockResponse(); - this.contextRunner.withPropertyValues(PREFIX + ".foo.identityprovider.metadata-url=" + metadataUrl) - .run((context) -> { - assertThat(context).hasSingleBean(RelyingPartyRegistrationRepository.class); - assertThat(this.server.getRequestCount()).isEqualTo(1); - }); + try (MockWebServer server = new MockWebServer()) { + server.start(); + String metadataUrl = server.url("").toString(); + setupMockResponse(server); + this.contextRunner.withPropertyValues(PREFIX + ".foo.identityprovider.metadata-uri=" + metadataUrl) + .run((context) -> { + assertThat(context).hasSingleBean(RelyingPartyRegistrationRepository.class); + assertThat(server.getRequestCount()).isEqualTo(1); + }); + } } @Test @@ -201,44 +195,12 @@ private boolean hasFilter(AssertableWebApplicationContext context, Class\n" + " \n" - + " \n" - + " \n" + " \n" + " \n" - + " \n" - + " MIIDZjCCAk6gAwIBAgIVAL9O+PA7SXtlwZZY8MVSE9On1cVWMA0GCSqGSIb3DQEB\n" - + " BQUAMCkxJzAlBgNVBAMTHmlkZW0tcHVwYWdlbnQuZG16LWludC51bmltby5pdDAe\n" - + " Fw0xMzA3MjQwMDQ0MTRaFw0zMzA3MjQwMDQ0MTRaMCkxJzAlBgNVBAMTHmlkZW0t\n" - + " cHVwYWdlbnQuZG16LWludC51bmltby5pdDCCASIwDQYJKoZIhvcNAMIIDQADggEP\n" - + " ADCCAQoCggEBAIAcp/VyzZGXUF99kwj4NvL/Rwv4YvBgLWzpCuoxqHZ/hmBwJtqS\n" - + " v0y9METBPFbgsF3hCISnxbcmNVxf/D0MoeKtw1YPbsUmow/bFe+r72hZ+IVAcejN\n" - + " iDJ7t5oTjsRN1t1SqvVVk6Ryk5AZhpFW+W9pE9N6c7kJ16Rp2/mbtax9OCzxpece\n" - + " byi1eiLfIBmkcRawL/vCc2v6VLI18i6HsNVO3l2yGosKCbuSoGDx2fCdAOk/rgdz\n" - + " cWOvFsIZSKuD+FVbSS/J9GVs7yotsS4PRl4iX9UMnfDnOMfO7bcBgbXtDl4SCU1v\n" - + " dJrRw7IL/pLz34Rv9a8nYitrzrxtLOp3nYUCAwEAAaOBhDCBgTBgBgMIIDEEWTBX\n" - + " gh5pZGVtLXB1cGFnZW50LmRtei1pbnQudW5pbW8uaXSGNWh0dHBzOi8vaWRlbS1w\n" - + " dXBhZ2VudC5kbXotaW50LnVuaW1vLml0L2lkcC9zaGliYm9sZXRoMB0GA1UdDgQW\n" - + " BBT8PANzz+adGnTRe8ldcyxAwe4VnzANBgkqhkiG9w0BAQUFAAOCAQEAOEnO8Clu\n" - + " 9z/Lf/8XOOsTdxJbV29DIF3G8KoQsB3dBsLwPZVEAQIP6ceS32Xaxrl6FMTDDNkL\n" - + " qUvvInUisw0+I5zZwYHybJQCletUWTnz58SC4C9G7FpuXHFZnOGtRcgGD1NOX4UU\n" - + " duus/4nVcGSLhDjszZ70Xtj0gw2Sn46oQPHTJ81QZ3Y9ih+Aj1c9OtUSBwtWZFkU\n" - + " yooAKoR8li68Yb21zN2N65AqV+ndL98M8xUYMKLONuAXStDeoVCipH6PJ09Z5U2p\n" - + " V5p4IQRV6QBsNw9CISJFuHzkVYTH5ZxzN80Ru46vh4y2M0Nu8GQ9I085KoZkrf5e\n" - + " Cq53OZt9ISjHEw==\n" + " \n" - + " \n" + " \n" + " \n" + " \n" - + " \n" + " \n" + " \n" - + " \n" - + " mailto:technical.contact@example.com\n" - + " \n" + " \n" + ""; - MockResponse mockResponse = new MockResponse().setBody(metadataResponse); - this.server.enqueue(mockResponse); + private void setupMockResponse(MockWebServer server) throws Exception { + try (InputStream metadataSource = new ClassPathResource("saml/idp-metadata").getInputStream()) { + Buffer metadataBuffer = new Buffer().readFrom(metadataSource); + MockResponse metadataResponse = new MockResponse().setBody(metadataBuffer); + server.enqueue(metadataResponse); + } } @Configuration(proxyBeanMethods = false) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java index 37d76e208b26..2027ff7eddd4 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/saml2/Saml2RelyingPartyPropertiesTests.java @@ -104,9 +104,9 @@ void customizeRelyingPartyEntityIdDefaultsToServiceProviderMetadata() { @Test void customizeIdentityProviderMetadataUrl() { - bind("spring.security.saml2.relyingparty.registration.simplesamlphp.identityprovider.metadata-url", + bind("spring.security.saml2.relyingparty.registration.simplesamlphp.identityprovider.metadata-uri", "https://idp.example.org/metadata"); - assertThat(this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getMetadataUrl()) + assertThat(this.properties.getRegistration().get("simplesamlphp").getIdentityprovider().getMetadataUri()) .isEqualTo("https://idp.example.org/metadata"); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/saml/idp-metadata b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/saml/idp-metadata new file mode 100644 index 000000000000..f11c34b2d4fe --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/saml/idp-metadata @@ -0,0 +1,42 @@ + + + + + + + MIIDZjCCAk6gAwIBAgIVAL9O+PA7SXtlwZZY8MVSE9On1cVWMA0GCSqGSIb3DQEB + BQUAMCkxJzAlBgNVBAMTHmlkZW0tcHVwYWdlbnQuZG16LWludC51bmltby5pdDAe + Fw0xMzA3MjQwMDQ0MTRaFw0zMzA3MjQwMDQ0MTRaMCkxJzAlBgNVBAMTHmlkZW0t + cHVwYWdlbnQuZG16LWludC51bmltby5pdDCCASIwDQYJKoZIhvcNAMIIDQADggEP + ADCCAQoCggEBAIAcp/VyzZGXUF99kwj4NvL/Rwv4YvBgLWzpCuoxqHZ/hmBwJtqS + v0y9METBPFbgsF3hCISnxbcmNVxf/D0MoeKtw1YPbsUmow/bFe+r72hZ+IVAcejN + iDJ7t5oTjsRN1t1SqvVVk6Ryk5AZhpFW+W9pE9N6c7kJ16Rp2/mbtax9OCzxpece + byi1eiLfIBmkcRawL/vCc2v6VLI18i6HsNVO3l2yGosKCbuSoGDx2fCdAOk/rgdz + cWOvFsIZSKuD+FVbSS/J9GVs7yotsS4PRl4iX9UMnfDnOMfO7bcBgbXtDl4SCU1v + dJrRw7IL/pLz34Rv9a8nYitrzrxtLOp3nYUCAwEAAaOBhDCBgTBgBgMIIDEEWTBX + gh5pZGVtLXB1cGFnZW50LmRtei1pbnQudW5pbW8uaXSGNWh0dHBzOi8vaWRlbS1w + dXBhZ2VudC5kbXotaW50LnVuaW1vLml0L2lkcC9zaGliYm9sZXRoMB0GA1UdDgQW + BBT8PANzz+adGnTRe8ldcyxAwe4VnzANBgkqhkiG9w0BAQUFAAOCAQEAOEnO8Clu + 9z/Lf/8XOOsTdxJbV29DIF3G8KoQsB3dBsLwPZVEAQIP6ceS32Xaxrl6FMTDDNkL + qUvvInUisw0+I5zZwYHybJQCletUWTnz58SC4C9G7FpuXHFZnOGtRcgGD1NOX4UU + duus/4nVcGSLhDjszZ70Xtj0gw2Sn46oQPHTJ81QZ3Y9ih+Aj1c9OtUSBwtWZFkU + yooAKoR8li68Yb21zN2N65AqV+ndL98M8xUYMKLONuAXStDeoVCipH6PJ09Z5U2p + V5p4IQRV6QBsNw9CISJFuHzkVYTH5ZxzN80Ru46vh4y2M0Nu8GQ9I085KoZkrf5e + Cq53OZt9ISjHEw== + + + + + + + + mailto:technical.contact@example.com + + \ No newline at end of file