mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-25 05:22:16 +00:00
Allow RelyingPartyRegistration Placeholder Resolution in XML
Closes gh-14645
This commit is contained in:
parent
689a4141df
commit
27294b2e11
@ -213,8 +213,10 @@ public final class RelyingPartyRegistrationsBeanDefinitionParser implements Bean
|
||||
private static RelyingPartyRegistration.Builder getBuilderFromMetadataLocationIfPossible(
|
||||
Element relyingPartyRegistrationElt, Map<String, Map<String, Object>> assertingParties,
|
||||
ParserContext parserContext) {
|
||||
String registrationId = relyingPartyRegistrationElt.getAttribute(ATT_REGISTRATION_ID);
|
||||
String metadataLocation = relyingPartyRegistrationElt.getAttribute(ATT_METADATA_LOCATION);
|
||||
String registrationId = resolveAttribute(parserContext,
|
||||
relyingPartyRegistrationElt.getAttribute(ATT_REGISTRATION_ID));
|
||||
String metadataLocation = resolveAttribute(parserContext,
|
||||
relyingPartyRegistrationElt.getAttribute(ATT_METADATA_LOCATION));
|
||||
RelyingPartyRegistration.Builder builder;
|
||||
if (StringUtils.hasText(metadataLocation)) {
|
||||
builder = RelyingPartyRegistrations.fromMetadataLocation(metadataLocation).registrationId(registrationId);
|
||||
@ -224,20 +226,20 @@ public final class RelyingPartyRegistrationsBeanDefinitionParser implements Bean
|
||||
.assertingPartyMetadata((apBuilder) -> buildAssertingParty(relyingPartyRegistrationElt,
|
||||
assertingParties, apBuilder, parserContext));
|
||||
}
|
||||
addRemainingProperties(relyingPartyRegistrationElt, builder);
|
||||
addRemainingProperties(parserContext, relyingPartyRegistrationElt, builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static void addRemainingProperties(Element relyingPartyRegistrationElt,
|
||||
private static void addRemainingProperties(ParserContext pc, Element relyingPartyRegistrationElt,
|
||||
RelyingPartyRegistration.Builder builder) {
|
||||
String entityId = relyingPartyRegistrationElt.getAttribute(ATT_ENTITY_ID);
|
||||
String singleLogoutServiceLocation = relyingPartyRegistrationElt
|
||||
.getAttribute(ATT_SINGLE_LOGOUT_SERVICE_LOCATION);
|
||||
String singleLogoutServiceResponseLocation = relyingPartyRegistrationElt
|
||||
.getAttribute(ATT_SINGLE_LOGOUT_SERVICE_RESPONSE_LOCATION);
|
||||
String entityId = resolveAttribute(pc, relyingPartyRegistrationElt.getAttribute(ATT_ENTITY_ID));
|
||||
String singleLogoutServiceLocation = resolveAttribute(pc,
|
||||
relyingPartyRegistrationElt.getAttribute(ATT_SINGLE_LOGOUT_SERVICE_LOCATION));
|
||||
String singleLogoutServiceResponseLocation = resolveAttribute(pc,
|
||||
relyingPartyRegistrationElt.getAttribute(ATT_SINGLE_LOGOUT_SERVICE_RESPONSE_LOCATION));
|
||||
Saml2MessageBinding singleLogoutServiceBinding = getSingleLogoutServiceBinding(relyingPartyRegistrationElt);
|
||||
String assertionConsumerServiceLocation = relyingPartyRegistrationElt
|
||||
.getAttribute(ATT_ASSERTION_CONSUMER_SERVICE_LOCATION);
|
||||
String assertionConsumerServiceLocation = resolveAttribute(pc,
|
||||
relyingPartyRegistrationElt.getAttribute(ATT_ASSERTION_CONSUMER_SERVICE_LOCATION));
|
||||
Saml2MessageBinding assertionConsumerServiceBinding = getAssertionConsumerServiceBinding(
|
||||
relyingPartyRegistrationElt);
|
||||
if (StringUtils.hasText(entityId)) {
|
||||
@ -400,4 +402,8 @@ public final class RelyingPartyRegistrationsBeanDefinitionParser implements Bean
|
||||
}
|
||||
}
|
||||
|
||||
private static String resolveAttribute(ParserContext pc, String value) {
|
||||
return pc.getReaderContext().getEnvironment().resolvePlaceholders(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ import org.springframework.security.saml2.provider.service.registration.InMemory
|
||||
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.Saml2MessageBinding;
|
||||
import org.springframework.security.saml2.provider.service.registration.TestRelyingPartyRegistrations;
|
||||
import org.springframework.security.saml2.provider.service.web.authentication.OpenSaml4AuthenticationRequestResolver;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ -288,6 +289,32 @@ public class RelyingPartyRegistrationsBeanDefinitionParserTests {
|
||||
verify(relayStateResolver).convert(request);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseWhenPlaceholdersThenResolves() throws Exception {
|
||||
RelyingPartyRegistration sample = TestRelyingPartyRegistrations.relyingPartyRegistration().build();
|
||||
System.setProperty("registration-id", sample.getRegistrationId());
|
||||
System.setProperty("entity-id", sample.getEntityId());
|
||||
System.setProperty("acs-location", sample.getAssertionConsumerServiceLocation());
|
||||
System.setProperty("slo-location", sample.getSingleLogoutServiceLocation());
|
||||
System.setProperty("slo-response-location", sample.getSingleLogoutServiceResponseLocation());
|
||||
try (MockWebServer web = new MockWebServer()) {
|
||||
web.start();
|
||||
String serverUrl = web.url("/metadata").toString();
|
||||
web.enqueue(xmlResponse(METADATA_RESPONSE));
|
||||
System.setProperty("metadata-location", serverUrl);
|
||||
this.spring.configLocations(xml("PlaceholderRegistration")).autowire();
|
||||
}
|
||||
RelyingPartyRegistration registration = this.relyingPartyRegistrationRepository
|
||||
.findByRegistrationId(sample.getRegistrationId());
|
||||
assertThat(registration.getRegistrationId()).isEqualTo(sample.getRegistrationId());
|
||||
assertThat(registration.getEntityId()).isEqualTo(sample.getEntityId());
|
||||
assertThat(registration.getAssertionConsumerServiceLocation())
|
||||
.isEqualTo(sample.getAssertionConsumerServiceLocation());
|
||||
assertThat(registration.getSingleLogoutServiceLocation()).isEqualTo(sample.getSingleLogoutServiceLocation());
|
||||
assertThat(registration.getSingleLogoutServiceResponseLocation())
|
||||
.isEqualTo(sample.getSingleLogoutServiceResponseLocation());
|
||||
}
|
||||
|
||||
private static MockResponse xmlResponse(String xml) {
|
||||
return new MockResponse().setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_XML_VALUE).setBody(xml);
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2002-2021 the original author or authors.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ https://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/security"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/security
|
||||
https://www.springframework.org/schema/security/spring-security.xsd
|
||||
http://www.springframework.org/schema/beans
|
||||
https://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<relying-party-registrations>
|
||||
<relying-party-registration registration-id="${registration-id}"
|
||||
entity-id="${entity-id}"
|
||||
metadata-location="${metadata-location}"
|
||||
assertion-consumer-service-location="${acs-location}"
|
||||
single-logout-service-location="${slo-location}"
|
||||
single-logout-service-response-location="${slo-response-location}"/>
|
||||
</relying-party-registrations>
|
||||
</b:beans>
|
Loading…
x
Reference in New Issue
Block a user