Use Sso Binding from SAML metadata uri if present

If the property is explicitly configured, that gets used.
If none are present, we rely on Spring Security's default value of
REDIRECT.

Fixes gh-26454
This commit is contained in:
Madhura Bhave
2021-05-24 16:37:31 -07:00
parent 942691753d
commit 8f2b180eb6
3 changed files with 55 additions and 2 deletions

View File

@@ -289,7 +289,7 @@ public class Saml2RelyingPartyProperties {
/**
* Whether to redirect or post authentication requests.
*/
private Saml2MessageBinding binding = Saml2MessageBinding.REDIRECT;
private Saml2MessageBinding binding;
/**
* Whether to sign authentication requests.

View File

@@ -98,7 +98,8 @@ class Saml2RelyingPartyRegistrationConfiguration {
Saml2RelyingPartyProperties.Identityprovider identityprovider = properties.getIdentityprovider();
return (details) -> {
map.from(identityprovider::getEntityId).to(details::entityId);
map.from(identityprovider.getSinglesignon()::getBinding).to(details::singleSignOnServiceBinding);
map.from(identityprovider.getSinglesignon()::getBinding).whenNonNull()
.to(details::singleSignOnServiceBinding);
map.from(identityprovider.getSinglesignon()::getUrl).to(details::singleSignOnServiceLocation);
map.from(identityprovider.getSinglesignon()::isSignRequest).when((signRequest) -> !usingMetadata)
.to(details::wantAuthnRequestsSigned);

View File

@@ -135,6 +135,50 @@ class Saml2RelyingPartyAutoConfigurationTests {
}
}
@Test
void autoconfigurationShouldUseBindingFromMetadataUrlIfPresent() throws Exception {
try (MockWebServer server = new MockWebServer()) {
server.start();
String metadataUrl = server.url("").toString();
setupMockResponse(server, new ClassPathResource("saml/idp-metadata"));
this.contextRunner.withPropertyValues(PREFIX + ".foo.identityprovider.metadata-uri=" + metadataUrl)
.run((context) -> {
RelyingPartyRegistrationRepository repository = context
.getBean(RelyingPartyRegistrationRepository.class);
RelyingPartyRegistration registration = repository.findByRegistrationId("foo");
assertThat(registration.getAssertingPartyDetails().getSingleSignOnServiceBinding())
.isEqualTo(Saml2MessageBinding.POST);
});
}
}
@Test
void autoconfigurationWhenMetadataUrlAndPropertyPresentShouldUseBindingFromProperty() throws Exception {
try (MockWebServer server = new MockWebServer()) {
server.start();
String metadataUrl = server.url("").toString();
setupMockResponse(server, new ClassPathResource("saml/idp-metadata"));
this.contextRunner.withPropertyValues(PREFIX + ".foo.identityprovider.metadata-uri=" + metadataUrl,
PREFIX + ".foo.identityprovider.singlesignon.binding=redirect").run((context) -> {
RelyingPartyRegistrationRepository repository = context
.getBean(RelyingPartyRegistrationRepository.class);
RelyingPartyRegistration registration = repository.findByRegistrationId("foo");
assertThat(registration.getAssertingPartyDetails().getSingleSignOnServiceBinding())
.isEqualTo(Saml2MessageBinding.REDIRECT);
});
}
}
@Test
void autoconfigurationWhenNoMetadataUrlOrPropertyPresentShouldUseRedirectBinding() {
this.contextRunner.withPropertyValues(getPropertyValuesWithoutSsoBinding()).run((context) -> {
RelyingPartyRegistrationRepository repository = context.getBean(RelyingPartyRegistrationRepository.class);
RelyingPartyRegistration registration = repository.findByRegistrationId("foo");
assertThat(registration.getAssertingPartyDetails().getSingleSignOnServiceBinding())
.isEqualTo(Saml2MessageBinding.REDIRECT);
});
}
@Test
void relyingPartyRegistrationRepositoryShouldBeConditionalOnMissingBean() {
this.contextRunner.withPropertyValues(getPropertyValues())
@@ -180,6 +224,14 @@ class Saml2RelyingPartyAutoConfigurationTests {
PREFIX + ".foo.identityprovider.verification.credentials[0].certificate-location=classpath:saml/certificate-location" };
}
private String[] getPropertyValuesWithoutSsoBinding() {
return new String[] { PREFIX
+ ".foo.identityprovider.singlesignon.url=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/SSOService.php",
PREFIX + ".foo.identityprovider.singlesignon.sign-request=false",
PREFIX + ".foo.identityprovider.entity-id=https://simplesaml-for-spring-saml.cfapps.io/saml2/idp/metadata.php",
PREFIX + ".foo.identityprovider.verification.credentials[0].certificate-location=classpath:saml/certificate-location" };
}
private String[] getPropertyValues() {
return new String[] {
PREFIX + ".foo.signing.credentials[0].private-key-location=classpath:saml/private-key-location",