Skip to content

Commit 538db29

Browse files
committed
Add RelyingPartyRegstration#mutate
Closes gh-12841
1 parent 97d1a49 commit 538db29

File tree

3 files changed

+57
-18
lines changed

3 files changed

+57
-18
lines changed

saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/registration/RelyingPartyRegistration.java

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,35 @@ private RelyingPartyRegistration(String registrationId, String entityId, String
130130
this.signingX509Credentials = Collections.unmodifiableList(new LinkedList<>(signingX509Credentials));
131131
}
132132

133+
/**
134+
* Copy the properties in this {@link RelyingPartyRegistration} into a {@link Builder}
135+
* @return a {@link Builder} based off of the properties in this
136+
* {@link RelyingPartyRegistration}
137+
* @since 6.1
138+
*/
139+
public Builder mutate() {
140+
AssertingPartyDetails party = this.assertingPartyDetails;
141+
return withRegistrationId(this.registrationId).entityId(this.entityId)
142+
.signingX509Credentials((c) -> c.addAll(this.signingX509Credentials))
143+
.decryptionX509Credentials((c) -> c.addAll(this.decryptionX509Credentials))
144+
.assertionConsumerServiceLocation(this.assertionConsumerServiceLocation)
145+
.assertionConsumerServiceBinding(this.assertionConsumerServiceBinding)
146+
.singleLogoutServiceLocation(this.singleLogoutServiceLocation)
147+
.singleLogoutServiceResponseLocation(this.singleLogoutServiceResponseLocation)
148+
.singleLogoutServiceBindings((c) -> c.addAll(this.singleLogoutServiceBindings))
149+
.nameIdFormat(this.nameIdFormat)
150+
.assertingPartyDetails((assertingParty) -> assertingParty.entityId(party.getEntityId())
151+
.wantAuthnRequestsSigned(party.getWantAuthnRequestsSigned())
152+
.signingAlgorithms((algorithms) -> algorithms.addAll(party.getSigningAlgorithms()))
153+
.verificationX509Credentials((c) -> c.addAll(party.getVerificationX509Credentials()))
154+
.encryptionX509Credentials((c) -> c.addAll(party.getEncryptionX509Credentials()))
155+
.singleSignOnServiceLocation(party.getSingleSignOnServiceLocation())
156+
.singleSignOnServiceBinding(party.getSingleSignOnServiceBinding())
157+
.singleLogoutServiceLocation(party.getSingleLogoutServiceLocation())
158+
.singleLogoutServiceResponseLocation(party.getSingleLogoutServiceResponseLocation())
159+
.singleLogoutServiceBinding(party.getSingleLogoutServiceBinding()));
160+
}
161+
133162
/**
134163
* Get the unique registration id for this RP/AP pair
135164
* @return the unique registration id for this RP/AP pair
@@ -292,7 +321,7 @@ public AssertingPartyDetails getAssertingPartyDetails() {
292321
*/
293322
public static Builder withRegistrationId(String registrationId) {
294323
Assert.hasText(registrationId, "registrationId cannot be empty");
295-
return new Builder(registrationId);
324+
return new Builder(registrationId, new AssertingPartyDetails.Builder());
296325
}
297326

298327
public static Builder withAssertingPartyDetails(AssertingPartyDetails assertingPartyDetails) {
@@ -315,7 +344,9 @@ public static Builder withAssertingPartyDetails(AssertingPartyDetails assertingP
315344
* object
316345
* @param registration the {@code RelyingPartyRegistration}
317346
* @return {@code Builder} to create a {@code RelyingPartyRegistration} object
347+
* @deprecated Use {@link #mutate()} instead
318348
*/
349+
@Deprecated(forRemoval = true, since = "6.1")
319350
public static Builder withRelyingPartyRegistration(RelyingPartyRegistration registration) {
320351
Assert.notNull(registration, "registration cannot be null");
321352
return withRegistrationId(registration.getRegistrationId()).entityId(registration.getEntityId())
@@ -736,9 +767,9 @@ public AssertingPartyDetails build() {
736767

737768
}
738769

739-
public static final class Builder {
770+
public static class Builder {
740771

741-
private Converter<AssertingPartyDetails, String> registrationId = AssertingPartyDetails::getEntityId;
772+
private String registrationId;
742773

743774
private String entityId = "{baseUrl}/saml2/service-provider-metadata/{registrationId}";
744775

@@ -760,13 +791,9 @@ public static final class Builder {
760791

761792
private AssertingPartyDetails.Builder assertingPartyDetailsBuilder;
762793

763-
private Builder(String registrationId) {
764-
this.registrationId = (party) -> registrationId;
765-
this.assertingPartyDetailsBuilder = new AssertingPartyDetails.Builder();
766-
}
767-
768-
Builder(AssertingPartyDetails.Builder builder) {
769-
this.assertingPartyDetailsBuilder = builder;
794+
protected Builder(String registrationId, AssertingPartyDetails.Builder assertingPartyDetailsBuilder) {
795+
this.registrationId = registrationId;
796+
this.assertingPartyDetailsBuilder = assertingPartyDetailsBuilder;
770797
}
771798

772799
/**
@@ -775,7 +802,7 @@ private Builder(String registrationId) {
775802
* @return this object
776803
*/
777804
public Builder registrationId(String id) {
778-
this.registrationId = (party) -> id;
805+
this.registrationId = id;
779806
return this;
780807
}
781808

@@ -974,11 +1001,11 @@ public RelyingPartyRegistration build() {
9741001
}
9751002

9761003
AssertingPartyDetails party = this.assertingPartyDetailsBuilder.build();
977-
String registrationId = this.registrationId.convert(party);
978-
return new RelyingPartyRegistration(registrationId, this.entityId, this.assertionConsumerServiceLocation,
979-
this.assertionConsumerServiceBinding, this.singleLogoutServiceLocation,
980-
this.singleLogoutServiceResponseLocation, this.singleLogoutServiceBindings, party,
981-
this.nameIdFormat, this.decryptionX509Credentials, this.signingX509Credentials);
1004+
return new RelyingPartyRegistration(this.registrationId, this.entityId,
1005+
this.assertionConsumerServiceLocation, this.assertionConsumerServiceBinding,
1006+
this.singleLogoutServiceLocation, this.singleLogoutServiceResponseLocation,
1007+
this.singleLogoutServiceBindings, party, this.nameIdFormat, this.decryptionX509Credentials,
1008+
this.signingX509Credentials);
9821009
}
9831010

9841011
}

saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/DefaultRelyingPartyRegistrationResolver.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,8 @@ public RelyingPartyRegistration resolve(HttpServletRequest request, String relyi
101101
.apply(relyingPartyRegistration.getSingleLogoutServiceLocation());
102102
String singleLogoutServiceResponseLocation = templateResolver
103103
.apply(relyingPartyRegistration.getSingleLogoutServiceResponseLocation());
104-
return RelyingPartyRegistration.withRelyingPartyRegistration(relyingPartyRegistration)
105-
.entityId(relyingPartyEntityId).assertionConsumerServiceLocation(assertionConsumerServiceLocation)
104+
return relyingPartyRegistration.mutate().entityId(relyingPartyEntityId)
105+
.assertionConsumerServiceLocation(assertionConsumerServiceLocation)
106106
.singleLogoutServiceLocation(singleLogoutServiceLocation)
107107
.singleLogoutServiceResponseLocation(singleLogoutServiceResponseLocation).build();
108108
}

saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/registration/RelyingPartyRegistrationTests.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,18 @@ public void withRelyingPartyRegistrationWorks() {
3838
compareRegistrations(registration, copy);
3939
}
4040

41+
@Test
42+
void mutateWhenInvokedThenCreatesCopy() {
43+
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.relyingPartyRegistration()
44+
.nameIdFormat("format")
45+
.assertingPartyDetails((a) -> a.singleSignOnServiceBinding(Saml2MessageBinding.POST))
46+
.assertingPartyDetails((a) -> a.wantAuthnRequestsSigned(false))
47+
.assertingPartyDetails((a) -> a.signingAlgorithms((algs) -> algs.add("alg")))
48+
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT).build();
49+
RelyingPartyRegistration copy = registration.mutate().build();
50+
compareRegistrations(registration, copy);
51+
}
52+
4153
private void compareRegistrations(RelyingPartyRegistration registration, RelyingPartyRegistration copy) {
4254
assertThat(copy.getRegistrationId()).isEqualTo(registration.getRegistrationId()).isEqualTo("simplesamlphp");
4355
assertThat(copy.getAssertingPartyDetails().getEntityId())

0 commit comments

Comments
 (0)