parent
dfa67fd8a1
commit
9d8888c5f0
|
@ -39,6 +39,7 @@ import org.springframework.core.io.Resource;
|
|||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.security.converter.RsaKeyConverters;
|
||||
import org.springframework.security.saml2.core.Saml2X509Credential;
|
||||
import org.springframework.security.saml2.provider.service.registration.AssertingPartyMetadata;
|
||||
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.RelyingPartyRegistrations;
|
||||
|
@ -153,7 +154,7 @@ public final class RelyingPartyRegistrationsBeanDefinitionParser implements Bean
|
|||
}
|
||||
|
||||
private static void addVerificationCredentials(Map<String, Object> assertingParty,
|
||||
RelyingPartyRegistration.AssertingPartyDetails.Builder builder) {
|
||||
AssertingPartyMetadata.Builder<?> builder) {
|
||||
List<String> verificationCertificateLocations = (List<String>) assertingParty.get(ELT_VERIFICATION_CREDENTIAL);
|
||||
List<Saml2X509Credential> verificationCredentials = new ArrayList<>();
|
||||
for (String certificateLocation : verificationCertificateLocations) {
|
||||
|
@ -163,7 +164,7 @@ public final class RelyingPartyRegistrationsBeanDefinitionParser implements Bean
|
|||
}
|
||||
|
||||
private static void addEncryptionCredentials(Map<String, Object> assertingParty,
|
||||
RelyingPartyRegistration.AssertingPartyDetails.Builder builder) {
|
||||
AssertingPartyMetadata.Builder<?> builder) {
|
||||
List<String> encryptionCertificateLocations = (List<String>) assertingParty.get(ELT_ENCRYPTION_CREDENTIAL);
|
||||
List<Saml2X509Credential> encryptionCredentials = new ArrayList<>();
|
||||
for (String certificateLocation : encryptionCertificateLocations) {
|
||||
|
@ -220,8 +221,8 @@ public final class RelyingPartyRegistrationsBeanDefinitionParser implements Bean
|
|||
}
|
||||
else {
|
||||
builder = RelyingPartyRegistration.withRegistrationId(registrationId)
|
||||
.assertingPartyDetails((apBuilder) -> buildAssertingParty(relyingPartyRegistrationElt, assertingParties,
|
||||
apBuilder, parserContext));
|
||||
.assertingPartyMetadata((apBuilder) -> buildAssertingParty(relyingPartyRegistrationElt,
|
||||
assertingParties, apBuilder, parserContext));
|
||||
}
|
||||
addRemainingProperties(relyingPartyRegistrationElt, builder);
|
||||
return builder;
|
||||
|
@ -260,7 +261,7 @@ public final class RelyingPartyRegistrationsBeanDefinitionParser implements Bean
|
|||
}
|
||||
|
||||
private static void buildAssertingParty(Element relyingPartyElt, Map<String, Map<String, Object>> assertingParties,
|
||||
RelyingPartyRegistration.AssertingPartyDetails.Builder builder, ParserContext parserContext) {
|
||||
AssertingPartyMetadata.Builder<?> builder, ParserContext parserContext) {
|
||||
String assertingPartyId = relyingPartyElt.getAttribute(ATT_ASSERTING_PARTY_ID);
|
||||
if (!assertingParties.containsKey(assertingPartyId)) {
|
||||
Object source = parserContext.extractSource(relyingPartyElt);
|
||||
|
@ -293,7 +294,7 @@ public final class RelyingPartyRegistrationsBeanDefinitionParser implements Bean
|
|||
}
|
||||
|
||||
private static void addSigningAlgorithms(Map<String, Object> assertingParty,
|
||||
RelyingPartyRegistration.AssertingPartyDetails.Builder builder) {
|
||||
AssertingPartyMetadata.Builder<?> builder) {
|
||||
String signingAlgorithmsAttr = getAsString(assertingParty, ATT_SIGNING_ALGORITHMS);
|
||||
if (StringUtils.hasText(signingAlgorithmsAttr)) {
|
||||
List<String> signingAlgorithms = Arrays.asList(signingAlgorithmsAttr.split(","));
|
||||
|
|
|
@ -114,7 +114,7 @@ Java::
|
|||
----
|
||||
RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistration.withRegistrationId("okta")
|
||||
// ...
|
||||
.assertingPartyDetails(party -> party
|
||||
.assertingPartyMetadata(party -> party
|
||||
// ...
|
||||
.wantAuthnRequestsSigned(false)
|
||||
)
|
||||
|
@ -128,7 +128,7 @@ Kotlin::
|
|||
var relyingPartyRegistration: RelyingPartyRegistration =
|
||||
RelyingPartyRegistration.withRegistrationId("okta")
|
||||
// ...
|
||||
.assertingPartyDetails { party: AssertingPartyDetails.Builder -> party
|
||||
.assertingPartyMetadata { party: AssertingPartyMetadata.Builder -> party
|
||||
// ...
|
||||
.wantAuthnRequestsSigned(false)
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ Java::
|
|||
String metadataLocation = "classpath:asserting-party-metadata.xml";
|
||||
RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistrations.fromMetadataLocation(metadataLocation)
|
||||
// ...
|
||||
.assertingPartyDetails((party) -> party
|
||||
.assertingPartyMetadata((party) -> party
|
||||
// ...
|
||||
.signingAlgorithms((sign) -> sign.add(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA512))
|
||||
)
|
||||
|
@ -169,7 +169,7 @@ var metadataLocation = "classpath:asserting-party-metadata.xml"
|
|||
var relyingPartyRegistration: RelyingPartyRegistration =
|
||||
RelyingPartyRegistrations.fromMetadataLocation(metadataLocation)
|
||||
// ...
|
||||
.assertingPartyDetails { party: AssertingPartyDetails.Builder -> party
|
||||
.assertingPartyMetadata { party: AssertingPartyMetadata.Builder -> party
|
||||
// ...
|
||||
.signingAlgorithms { sign: MutableList<String?> ->
|
||||
sign.add(
|
||||
|
@ -197,7 +197,7 @@ Java::
|
|||
----
|
||||
RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistration.withRegistrationId("okta")
|
||||
// ...
|
||||
.assertingPartyDetails(party -> party
|
||||
.assertingPartyMetadata(party -> party
|
||||
// ...
|
||||
.singleSignOnServiceBinding(Saml2MessageBinding.POST)
|
||||
)
|
||||
|
@ -211,7 +211,7 @@ Kotlin::
|
|||
var relyingPartyRegistration: RelyingPartyRegistration? =
|
||||
RelyingPartyRegistration.withRegistrationId("okta")
|
||||
// ...
|
||||
.assertingPartyDetails { party: AssertingPartyDetails.Builder -> party
|
||||
.assertingPartyMetadata { party: AssertingPartyMetadata.Builder -> party
|
||||
// ...
|
||||
.singleSignOnServiceBinding(Saml2MessageBinding.POST)
|
||||
}
|
||||
|
|
|
@ -484,7 +484,7 @@ public RelyingPartyRegistrationRepository relyingPartyRegistrations() throws Exc
|
|||
Saml2X509Credential credential = Saml2X509Credential.verification(certificate);
|
||||
RelyingPartyRegistration registration = RelyingPartyRegistration
|
||||
.withRegistrationId("example")
|
||||
.assertingPartyDetails(party -> party
|
||||
.assertingPartyMetadata(party -> party
|
||||
.entityId("https://idp.example.com/issuer")
|
||||
.singleSignOnServiceLocation("https://idp.example.com/SSO.saml2")
|
||||
.wantAuthnRequestsSigned(false)
|
||||
|
@ -508,7 +508,7 @@ open fun relyingPartyRegistrations(): RelyingPartyRegistrationRepository {
|
|||
val credential: Saml2X509Credential = Saml2X509Credential.verification(certificate)
|
||||
val registration = RelyingPartyRegistration
|
||||
.withRegistrationId("example")
|
||||
.assertingPartyDetails { party: AssertingPartyDetails.Builder ->
|
||||
.assertingPartyMetadata { party: AssertingPartyMetadata.Builder ->
|
||||
party
|
||||
.entityId("https://idp.example.com/issuer")
|
||||
.singleSignOnServiceLocation("https://idp.example.com/SSO.saml2")
|
||||
|
@ -699,7 +699,7 @@ RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistration.wit
|
|||
.entityId("{baseUrl}/{registrationId}")
|
||||
.decryptionX509Credentials(c -> c.add(relyingPartyDecryptingCredential()))
|
||||
.assertionConsumerServiceLocation("/my-login-endpoint/{registrationId}")
|
||||
.assertingPartyDetails(party -> party
|
||||
.assertingPartyMetadata(party -> party
|
||||
.entityId("https://ap.example.org")
|
||||
.verificationX509Credentials(c -> c.add(assertingPartyVerifyingCredential()))
|
||||
.singleSignOnServiceLocation("https://ap.example.org/SSO.saml2")
|
||||
|
@ -718,7 +718,7 @@ val relyingPartyRegistration =
|
|||
c.add(relyingPartyDecryptingCredential())
|
||||
}
|
||||
.assertionConsumerServiceLocation("/my-login-endpoint/{registrationId}")
|
||||
.assertingPartyDetails { party -> party
|
||||
.assertingPartyMetadata { party -> party
|
||||
.entityId("https://ap.example.org")
|
||||
.verificationX509Credentials { c -> c.add(assertingPartyVerifyingCredential()) }
|
||||
.singleSignOnServiceLocation("https://ap.example.org/SSO.saml2")
|
||||
|
@ -730,7 +730,7 @@ val relyingPartyRegistration =
|
|||
[TIP]
|
||||
====
|
||||
The top-level metadata methods are details about the relying party.
|
||||
The methods inside `assertingPartyDetails` are details about the asserting party.
|
||||
The methods inside `AssertingPartyMetadata` are details about the asserting party.
|
||||
====
|
||||
|
||||
[NOTE]
|
||||
|
|
|
@ -339,7 +339,7 @@ It's common to need to set other values in the `<saml2:LogoutRequest>` than the
|
|||
|
||||
By default, Spring Security will issue a `<saml2:LogoutRequest>` and supply:
|
||||
|
||||
* The `Destination` attribute - from `RelyingPartyRegistration#getAssertingPartyDetails#getSingleLogoutServiceLocation`
|
||||
* The `Destination` attribute - from `RelyingPartyRegistration#getAssertingPartyMetadata#getSingleLogoutServiceLocation`
|
||||
* The `ID` attribute - a GUID
|
||||
* The `<Issuer>` element - from `RelyingPartyRegistration#getEntityId`
|
||||
* The `<NameID>` element - from `Authentication#getName`
|
||||
|
@ -424,7 +424,7 @@ It's common to need to set other values in the `<saml2:LogoutResponse>` than the
|
|||
|
||||
By default, Spring Security will issue a `<saml2:LogoutResponse>` and supply:
|
||||
|
||||
* The `Destination` attribute - from `RelyingPartyRegistration#getAssertingPartyDetails#getSingleLogoutServiceResponseLocation`
|
||||
* The `Destination` attribute - from `RelyingPartyRegistration#getAssertingPartyMetadata#getSingleLogoutServiceResponseLocation`
|
||||
* The `ID` attribute - a GUID
|
||||
* The `<Issuer>` element - from `RelyingPartyRegistration#getEntityId`
|
||||
* The `<Status>` element - `SUCCESS`
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
[[servlet-saml2login-metadata]]
|
||||
= Saml 2.0 Metadata
|
||||
|
||||
Spring Security can <<parsing-asserting-party-metadata,parse asserting party metadata>> to produce an `AssertingPartyDetails` instance as well as <<publishing-relying-party-metadata,publish relying party metadata>> from a `RelyingPartyRegistration` instance.
|
||||
Spring Security can <<parsing-asserting-party-metadata,parse asserting party metadata>> to produce an `AssertingPartyMetadata` instance as well as <<publishing-relying-party-metadata,publish relying party metadata>> from a `RelyingPartyRegistration` instance.
|
||||
|
||||
[[parsing-asserting-party-metadata]]
|
||||
== Parsing `<saml2:IDPSSODescriptor>` metadata
|
||||
|
||||
You can parse an asserting party's metadata xref:servlet/saml2/login/overview.adoc#servlet-saml2login-relyingpartyregistrationrepository[using `RelyingPartyRegistrations`].
|
||||
|
||||
When using the OpenSAML vendor support, the resulting `AssertingPartyDetails` will be of type `OpenSamlAssertingPartyDetails`.
|
||||
When using the OpenSAML vendor support, the resulting `AssertingPartyMetadata` will be of type `OpenSamlAssertingPartyDetails`.
|
||||
This means you'll be able to do get the underlying OpenSAML XMLObject by doing the following:
|
||||
|
||||
[tabs]
|
||||
|
@ -18,7 +18,7 @@ Java::
|
|||
[source,java,role="primary"]
|
||||
----
|
||||
OpenSamlAssertingPartyDetails details = (OpenSamlAssertingPartyDetails)
|
||||
registration.getAssertingPartyDetails();
|
||||
registration.getAssertingPartyMetadata();
|
||||
EntityDescriptor openSamlEntityDescriptor = details.getEntityDescriptor();
|
||||
----
|
||||
|
||||
|
@ -27,7 +27,7 @@ Kotlin::
|
|||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
val details: OpenSamlAssertingPartyDetails =
|
||||
registration.getAssertingPartyDetails() as OpenSamlAssertingPartyDetails
|
||||
registration.getAssertingPartyMetadata() as OpenSamlAssertingPartyDetails
|
||||
val openSamlEntityDescriptor: EntityDescriptor = details.getEntityDescriptor()
|
||||
----
|
||||
======
|
||||
|
@ -76,8 +76,7 @@ public class RefreshableRelyingPartyRegistrationRepository
|
|||
}
|
||||
|
||||
private RelyingPartyRegistration applyRelyingParty(AssertingPartyMetadata metadata) {
|
||||
AssertingPartyDetails details = (AssertingPartyDetails) metadata;
|
||||
return RelyingPartyRegistration.withAssertingPartyDetails(details)
|
||||
return RelyingPartyRegistration.withAssertingPartyMetadata(metadata)
|
||||
// apply any relying party configuration
|
||||
.build();
|
||||
}
|
||||
|
@ -110,8 +109,8 @@ class RefreshableRelyingPartyRegistrationRepository : IterableRelyingPartyRegist
|
|||
}
|
||||
|
||||
private fun applyRelyingParty(metadata: AssertingPartyMetadata): RelyingPartyRegistration {
|
||||
val details: AssertingPartyDetails = metadata as AssertingPartyDetails
|
||||
return RelyingPartyRegistration.withAssertingPartyDetails(details)
|
||||
val details: AssertingPartyMetadata = metadata as AssertingPartyMetadata
|
||||
return RelyingPartyRegistration.withAssertingPartyMetadata(details)
|
||||
// apply any relying party configuration
|
||||
.build()
|
||||
}
|
||||
|
|
|
@ -400,7 +400,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
|
|||
result = result.concat(new Saml2Error(Saml2ErrorCodes.INVALID_DESTINATION, message));
|
||||
}
|
||||
String assertingPartyEntityId = token.getRelyingPartyRegistration()
|
||||
.getAssertingPartyDetails()
|
||||
.getAssertingPartyMetadata()
|
||||
.getEntityId();
|
||||
if (!StringUtils.hasText(issuer) || !issuer.equals(assertingPartyEntityId)) {
|
||||
String message = String.format("Invalid issuer [%s] for SAML response [%s]", issuer, response.getID());
|
||||
|
@ -775,7 +775,7 @@ public final class OpenSaml4AuthenticationProvider implements AuthenticationProv
|
|||
RelyingPartyRegistration relyingPartyRegistration = token.getRelyingPartyRegistration();
|
||||
String audience = relyingPartyRegistration.getEntityId();
|
||||
String recipient = relyingPartyRegistration.getAssertionConsumerServiceLocation();
|
||||
String assertingPartyEntityId = relyingPartyRegistration.getAssertingPartyDetails().getEntityId();
|
||||
String assertingPartyEntityId = relyingPartyRegistration.getAssertingPartyMetadata().getEntityId();
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
Assertion assertion = assertionToken.getAssertion();
|
||||
if (assertionContainsInResponseTo(assertion)) {
|
||||
|
|
|
@ -96,7 +96,7 @@ final class OpenSamlSigningUtils {
|
|||
private static SignatureSigningParameters resolveSigningParameters(
|
||||
RelyingPartyRegistration relyingPartyRegistration) {
|
||||
List<Credential> credentials = resolveSigningCredentials(relyingPartyRegistration);
|
||||
List<String> algorithms = relyingPartyRegistration.getAssertingPartyDetails().getSigningAlgorithms();
|
||||
List<String> algorithms = relyingPartyRegistration.getAssertingPartyMetadata().getSigningAlgorithms();
|
||||
List<String> digests = Collections.singletonList(SignatureConstants.ALGO_ID_DIGEST_SHA256);
|
||||
String canonicalization = SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
|
||||
SignatureSigningParametersResolver resolver = new SAMLMetadataSignatureSigningParametersResolver();
|
||||
|
|
|
@ -73,11 +73,12 @@ final class OpenSamlVerificationUtils {
|
|||
|
||||
static SignatureTrustEngine trustEngine(RelyingPartyRegistration registration) {
|
||||
Set<Credential> credentials = new HashSet<>();
|
||||
Collection<Saml2X509Credential> keys = registration.getAssertingPartyDetails().getVerificationX509Credentials();
|
||||
Collection<Saml2X509Credential> keys = registration.getAssertingPartyMetadata()
|
||||
.getVerificationX509Credentials();
|
||||
for (Saml2X509Credential key : keys) {
|
||||
BasicX509Credential cred = new BasicX509Credential(key.getCertificate());
|
||||
cred.setUsageType(UsageType.SIGNING);
|
||||
cred.setEntityId(registration.getAssertingPartyDetails().getEntityId());
|
||||
cred.setEntityId(registration.getAssertingPartyMetadata().getEntityId());
|
||||
credentials.add(cred);
|
||||
}
|
||||
CredentialResolver credentialsResolver = new CollectionCredentialResolver(credentials);
|
||||
|
|
|
@ -50,7 +50,7 @@ public class Saml2PostAuthenticationRequest extends AbstractSaml2AuthenticationR
|
|||
* @since 5.7
|
||||
*/
|
||||
public static Builder withRelyingPartyRegistration(RelyingPartyRegistration registration) {
|
||||
String location = registration.getAssertingPartyDetails().getSingleSignOnServiceLocation();
|
||||
String location = registration.getAssertingPartyMetadata().getSingleSignOnServiceLocation();
|
||||
return new Builder(registration).authenticationRequestUri(location);
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ public final class Saml2RedirectAuthenticationRequest extends AbstractSaml2Authe
|
|||
* @since 5.7
|
||||
*/
|
||||
public static Builder withRelyingPartyRegistration(RelyingPartyRegistration registration) {
|
||||
String location = registration.getAssertingPartyDetails().getSingleSignOnServiceLocation();
|
||||
String location = registration.getAssertingPartyMetadata().getSingleSignOnServiceLocation();
|
||||
return new Builder(registration).authenticationRequestUri(location);
|
||||
}
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ public final class OpenSamlLogoutRequestValidator implements Saml2LogoutRequestV
|
|||
return;
|
||||
}
|
||||
String issuer = request.getIssuer().getValue();
|
||||
if (!issuer.equals(registration.getAssertingPartyDetails().getEntityId())) {
|
||||
if (!issuer.equals(registration.getAssertingPartyMetadata().getEntityId())) {
|
||||
errors
|
||||
.add(new Saml2Error(Saml2ErrorCodes.INVALID_ISSUER, "Failed to match issuer to configured issuer"));
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ public class OpenSamlLogoutResponseValidator implements Saml2LogoutResponseValid
|
|||
return;
|
||||
}
|
||||
String issuer = response.getIssuer().getValue();
|
||||
if (!issuer.equals(registration.getAssertingPartyDetails().getEntityId())) {
|
||||
if (!issuer.equals(registration.getAssertingPartyMetadata().getEntityId())) {
|
||||
errors
|
||||
.add(new Saml2Error(Saml2ErrorCodes.INVALID_ISSUER, "Failed to match issuer to configured issuer"));
|
||||
}
|
||||
|
|
|
@ -164,12 +164,12 @@ final class OpenSamlVerificationUtils {
|
|||
|
||||
private SignatureTrustEngine trustEngine(RelyingPartyRegistration registration) {
|
||||
Set<Credential> credentials = new HashSet<>();
|
||||
Collection<Saml2X509Credential> keys = registration.getAssertingPartyDetails()
|
||||
Collection<Saml2X509Credential> keys = registration.getAssertingPartyMetadata()
|
||||
.getVerificationX509Credentials();
|
||||
for (Saml2X509Credential key : keys) {
|
||||
BasicX509Credential cred = new BasicX509Credential(key.getCertificate());
|
||||
cred.setUsageType(UsageType.SIGNING);
|
||||
cred.setEntityId(registration.getAssertingPartyDetails().getEntityId());
|
||||
cred.setEntityId(registration.getAssertingPartyMetadata().getEntityId());
|
||||
credentials.add(cred);
|
||||
}
|
||||
CredentialResolver credentialsResolver = new CollectionCredentialResolver(credentials);
|
||||
|
|
|
@ -190,8 +190,8 @@ public final class Saml2LogoutRequest implements Serializable {
|
|||
|
||||
private Builder(RelyingPartyRegistration registration) {
|
||||
this.registration = registration;
|
||||
this.location = registration.getAssertingPartyDetails().getSingleLogoutServiceLocation();
|
||||
this.binding = registration.getAssertingPartyDetails().getSingleLogoutServiceBinding();
|
||||
this.location = registration.getAssertingPartyMetadata().getSingleLogoutServiceLocation();
|
||||
this.binding = registration.getAssertingPartyMetadata().getSingleLogoutServiceBinding();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -156,8 +156,8 @@ public final class Saml2LogoutResponse {
|
|||
private Function<Map<String, String>, String> encoder = DEFAULT_ENCODER;
|
||||
|
||||
private Builder(RelyingPartyRegistration registration) {
|
||||
this.location = registration.getAssertingPartyDetails().getSingleLogoutServiceResponseLocation();
|
||||
this.binding = registration.getAssertingPartyDetails().getSingleLogoutServiceBinding();
|
||||
this.location = registration.getAssertingPartyMetadata().getSingleLogoutServiceResponseLocation();
|
||||
this.binding = registration.getAssertingPartyMetadata().getSingleLogoutServiceBinding();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -80,7 +80,7 @@ final class OpenSamlSigningUtils {
|
|||
}
|
||||
|
||||
static <O extends SignableXMLObject> O sign(O object, RelyingPartyRegistration relyingPartyRegistration) {
|
||||
List<String> algorithms = relyingPartyRegistration.getAssertingPartyDetails().getSigningAlgorithms();
|
||||
List<String> algorithms = relyingPartyRegistration.getAssertingPartyMetadata().getSigningAlgorithms();
|
||||
List<Credential> credentials = resolveSigningCredentials(relyingPartyRegistration);
|
||||
return sign(object, algorithms, credentials);
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ final class OpenSamlSigningUtils {
|
|||
private static SignatureSigningParameters resolveSigningParameters(
|
||||
RelyingPartyRegistration relyingPartyRegistration) {
|
||||
List<Credential> credentials = resolveSigningCredentials(relyingPartyRegistration);
|
||||
List<String> algorithms = relyingPartyRegistration.getAssertingPartyDetails().getSigningAlgorithms();
|
||||
List<String> algorithms = relyingPartyRegistration.getAssertingPartyMetadata().getSigningAlgorithms();
|
||||
return resolveSigningParameters(algorithms, credentials);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ public class InMemoryRelyingPartyRegistrationRepository implements IterableRelyi
|
|||
Collection<RelyingPartyRegistration> rps) {
|
||||
MultiValueMap<String, RelyingPartyRegistration> result = new LinkedMultiValueMap<>();
|
||||
for (RelyingPartyRegistration rp : rps) {
|
||||
result.add(rp.getAssertingPartyDetails().getEntityId(), rp);
|
||||
result.add(rp.getAssertingPartyMetadata().getEntityId(), rp);
|
||||
}
|
||||
return Collections.unmodifiableMap(result);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ import org.springframework.security.saml2.core.Saml2X509Credential;
|
|||
* EntityDescriptor descriptor = openSamlRegistration.getAssertingPartyDetails.getEntityDescriptor();
|
||||
* }
|
||||
* </pre> do instead: <pre>
|
||||
* if (registration.getAssertingPartyDetails() instanceof openSamlAssertingPartyDetails) {
|
||||
* if (registration.getAssertingPartyMetadata() instanceof openSamlAssertingPartyDetails) {
|
||||
* EntityDescriptor descriptor = openSamlAssertingPartyDetails.getEntityDescriptor();
|
||||
* }
|
||||
* </pre>
|
||||
|
@ -170,6 +170,11 @@ public final class OpenSamlRelyingPartyRegistration extends RelyingPartyRegistra
|
|||
return (Builder) super.assertingPartyDetails(assertingPartyDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder assertingPartyMetadata(Consumer<AssertingPartyMetadata.Builder<?>> assertingPartyMetadata) {
|
||||
return (Builder) super.assertingPartyMetadata(assertingPartyMetadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an {@link OpenSamlRelyingPartyRegistration}
|
||||
* {@link org.springframework.security.saml2.provider.service.registration.OpenSamlRelyingPartyRegistration}
|
||||
|
|
|
@ -88,7 +88,7 @@ public class RelyingPartyRegistration {
|
|||
|
||||
private final boolean authnRequestsSigned;
|
||||
|
||||
private final AssertingPartyDetails assertingPartyDetails;
|
||||
private final AssertingPartyMetadata assertingPartyMetadata;
|
||||
|
||||
private final Collection<Saml2X509Credential> decryptionX509Credentials;
|
||||
|
||||
|
@ -127,7 +127,45 @@ public class RelyingPartyRegistration {
|
|||
this.singleLogoutServiceBindings = Collections.unmodifiableList(new LinkedList<>(singleLogoutServiceBindings));
|
||||
this.nameIdFormat = nameIdFormat;
|
||||
this.authnRequestsSigned = authnRequestsSigned;
|
||||
this.assertingPartyDetails = assertingPartyDetails;
|
||||
this.assertingPartyMetadata = assertingPartyDetails;
|
||||
this.decryptionX509Credentials = Collections.unmodifiableList(new LinkedList<>(decryptionX509Credentials));
|
||||
this.signingX509Credentials = Collections.unmodifiableList(new LinkedList<>(signingX509Credentials));
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration(String registrationId, String entityId, String assertionConsumerServiceLocation,
|
||||
Saml2MessageBinding assertionConsumerServiceBinding, String singleLogoutServiceLocation,
|
||||
String singleLogoutServiceResponseLocation, Collection<Saml2MessageBinding> singleLogoutServiceBindings,
|
||||
AssertingPartyMetadata assertingPartyMetadata, String nameIdFormat, boolean authnRequestsSigned,
|
||||
Collection<Saml2X509Credential> decryptionX509Credentials,
|
||||
Collection<Saml2X509Credential> signingX509Credentials) {
|
||||
Assert.hasText(registrationId, "registrationId cannot be empty");
|
||||
Assert.hasText(entityId, "entityId cannot be empty");
|
||||
Assert.hasText(assertionConsumerServiceLocation, "assertionConsumerServiceLocation cannot be empty");
|
||||
Assert.notNull(assertionConsumerServiceBinding, "assertionConsumerServiceBinding cannot be null");
|
||||
Assert.isTrue(singleLogoutServiceLocation == null || !CollectionUtils.isEmpty(singleLogoutServiceBindings),
|
||||
"singleLogoutServiceBindings cannot be null or empty when singleLogoutServiceLocation is set");
|
||||
Assert.notNull(assertingPartyMetadata, "assertingPartyDetails cannot be null");
|
||||
Assert.notNull(decryptionX509Credentials, "decryptionX509Credentials cannot be null");
|
||||
for (Saml2X509Credential c : decryptionX509Credentials) {
|
||||
Assert.notNull(c, "decryptionX509Credentials cannot contain null elements");
|
||||
Assert.isTrue(c.isDecryptionCredential(),
|
||||
"All decryptionX509Credentials must have a usage of DECRYPTION set");
|
||||
}
|
||||
Assert.notNull(signingX509Credentials, "signingX509Credentials cannot be null");
|
||||
for (Saml2X509Credential c : signingX509Credentials) {
|
||||
Assert.notNull(c, "signingX509Credentials cannot contain null elements");
|
||||
Assert.isTrue(c.isSigningCredential(), "All signingX509Credentials must have a usage of SIGNING set");
|
||||
}
|
||||
this.registrationId = registrationId;
|
||||
this.entityId = entityId;
|
||||
this.assertionConsumerServiceLocation = assertionConsumerServiceLocation;
|
||||
this.assertionConsumerServiceBinding = assertionConsumerServiceBinding;
|
||||
this.singleLogoutServiceLocation = singleLogoutServiceLocation;
|
||||
this.singleLogoutServiceResponseLocation = singleLogoutServiceResponseLocation;
|
||||
this.singleLogoutServiceBindings = Collections.unmodifiableList(new LinkedList<>(singleLogoutServiceBindings));
|
||||
this.nameIdFormat = nameIdFormat;
|
||||
this.authnRequestsSigned = authnRequestsSigned;
|
||||
this.assertingPartyMetadata = assertingPartyMetadata;
|
||||
this.decryptionX509Credentials = Collections.unmodifiableList(new LinkedList<>(decryptionX509Credentials));
|
||||
this.signingX509Credentials = Collections.unmodifiableList(new LinkedList<>(signingX509Credentials));
|
||||
}
|
||||
|
@ -139,7 +177,7 @@ public class RelyingPartyRegistration {
|
|||
* @since 6.1
|
||||
*/
|
||||
public Builder mutate() {
|
||||
return new Builder(this.registrationId, this.assertingPartyDetails.mutate()).entityId(this.entityId)
|
||||
return new Builder(this.registrationId, this.assertingPartyMetadata.mutate()).entityId(this.entityId)
|
||||
.signingX509Credentials((c) -> c.addAll(this.signingX509Credentials))
|
||||
.decryptionX509Credentials((c) -> c.addAll(this.decryptionX509Credentials))
|
||||
.assertionConsumerServiceLocation(this.assertionConsumerServiceLocation)
|
||||
|
@ -317,9 +355,22 @@ public class RelyingPartyRegistration {
|
|||
* Get the configuration details for the Asserting Party
|
||||
* @return the {@link AssertingPartyDetails}
|
||||
* @since 5.4
|
||||
* @deprecated Use {@link #getAssertingPartyMetadata()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public AssertingPartyDetails getAssertingPartyDetails() {
|
||||
return this.assertingPartyDetails;
|
||||
Assert.isInstanceOf(AssertingPartyDetails.class, this.assertingPartyMetadata,
|
||||
"This class was initialized with an AssertingPartyMetadata, please call #getAssertingPartyMetadata instead");
|
||||
return (AssertingPartyDetails) this.assertingPartyMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the metadata for the Asserting Party
|
||||
* @return the {@link AssertingPartyDetails}
|
||||
* @since 6.4
|
||||
*/
|
||||
public AssertingPartyMetadata getAssertingPartyMetadata() {
|
||||
return this.assertingPartyMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -333,6 +384,12 @@ public class RelyingPartyRegistration {
|
|||
return new Builder(registrationId, new AssertingPartyDetails.Builder());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param assertingPartyDetails the asserting party metadata
|
||||
* @return {@code Builder} to create a {@code RelyingPartyRegistration} object
|
||||
* @deprecated Use {@link #withAssertingPartyMetadata} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "6.4")
|
||||
public static Builder withAssertingPartyDetails(AssertingPartyDetails assertingPartyDetails) {
|
||||
Assert.notNull(assertingPartyDetails, "assertingPartyDetails cannot be null");
|
||||
return new Builder(assertingPartyDetails.getEntityId(), assertingPartyDetails.mutate());
|
||||
|
@ -353,8 +410,8 @@ public class RelyingPartyRegistration {
|
|||
* @since 6.4
|
||||
*/
|
||||
public static Builder withAssertingPartyMetadata(AssertingPartyMetadata metadata) {
|
||||
Assert.isInstanceOf(AssertingPartyDetails.class, metadata, "metadata must be of type AssertingPartyDetails");
|
||||
return withAssertingPartyDetails((AssertingPartyDetails) metadata);
|
||||
Assert.notNull(metadata, "assertingPartyMetadata cannot be null");
|
||||
return new Builder(metadata.getEntityId(), metadata.mutate());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -819,11 +876,11 @@ public class RelyingPartyRegistration {
|
|||
|
||||
private boolean authnRequestsSigned = false;
|
||||
|
||||
private AssertingPartyDetails.Builder assertingPartyDetailsBuilder;
|
||||
private AssertingPartyMetadata.Builder<?> assertingPartyMetadataBuilder;
|
||||
|
||||
protected Builder(String registrationId, AssertingPartyDetails.Builder assertingPartyDetailsBuilder) {
|
||||
protected Builder(String registrationId, AssertingPartyMetadata.Builder<?> assertingPartyMetadataBuilder) {
|
||||
this.registrationId = registrationId;
|
||||
this.assertingPartyDetailsBuilder = assertingPartyDetailsBuilder;
|
||||
this.assertingPartyMetadataBuilder = assertingPartyMetadataBuilder;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1028,9 +1085,24 @@ public class RelyingPartyRegistration {
|
|||
* @param assertingPartyDetails The {@link Consumer} to apply
|
||||
* @return the {@link Builder} for further configuration
|
||||
* @since 5.4
|
||||
* @deprecated Use {@link #assertingPartyMetadata} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "6.4")
|
||||
public Builder assertingPartyDetails(Consumer<AssertingPartyDetails.Builder> assertingPartyDetails) {
|
||||
assertingPartyDetails.accept(this.assertingPartyDetailsBuilder);
|
||||
Assert.isInstanceOf(AssertingPartyDetails.Builder.class, this.assertingPartyMetadataBuilder,
|
||||
"This class was constructed with an AssertingPartyMetadata instance, as such, please use #assertingPartyMetadata");
|
||||
assertingPartyDetails.accept((AssertingPartyDetails.Builder) this.assertingPartyMetadataBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply this {@link Consumer} to further configure the Asserting Party metadata
|
||||
* @param assertingPartyMetadata The {@link Consumer} to apply
|
||||
* @return the {@link Builder} for further configuration
|
||||
* @since 6.4
|
||||
*/
|
||||
public Builder assertingPartyMetadata(Consumer<AssertingPartyMetadata.Builder<?>> assertingPartyMetadata) {
|
||||
assertingPartyMetadata.accept(this.assertingPartyMetadataBuilder);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -1048,7 +1120,7 @@ public class RelyingPartyRegistration {
|
|||
this.singleLogoutServiceBindings.add(Saml2MessageBinding.POST);
|
||||
}
|
||||
|
||||
AssertingPartyDetails party = this.assertingPartyDetailsBuilder.build();
|
||||
AssertingPartyMetadata party = this.assertingPartyMetadataBuilder.build();
|
||||
return new RelyingPartyRegistration(this.registrationId, this.entityId,
|
||||
this.assertionConsumerServiceLocation, this.assertionConsumerServiceBinding,
|
||||
this.singleLogoutServiceLocation, this.singleLogoutServiceResponseLocation,
|
||||
|
|
|
@ -68,7 +68,7 @@ public final class RelyingPartyRegistrationPlaceholderResolvers {
|
|||
*/
|
||||
public static UriResolver uriResolver(HttpServletRequest request, RelyingPartyRegistration registration) {
|
||||
String relyingPartyEntityId = registration.getEntityId();
|
||||
String assertingPartyEntityId = registration.getAssertingPartyDetails().getEntityId();
|
||||
String assertingPartyEntityId = registration.getAssertingPartyMetadata().getEntityId();
|
||||
String registrationId = registration.getRegistrationId();
|
||||
Map<String, String> uriVariables = uriVariables(request);
|
||||
uriVariables.put("relyingPartyEntityId", StringUtils.hasText(relyingPartyEntityId) ? relyingPartyEntityId : "");
|
||||
|
|
|
@ -146,7 +146,7 @@ class OpenSamlAuthenticationRequestResolver {
|
|||
Issuer iss = this.issuerBuilder.buildObject();
|
||||
iss.setValue(entityId);
|
||||
authnRequest.setIssuer(iss);
|
||||
authnRequest.setDestination(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
|
||||
authnRequest.setDestination(registration.getAssertingPartyMetadata().getSingleSignOnServiceLocation());
|
||||
authnRequest.setAssertionConsumerServiceURL(assertionConsumerServiceLocation);
|
||||
if (registration.getNameIdFormat() != null) {
|
||||
NameIDPolicy nameIdPolicy = this.nameIdPolicyBuilder.buildObject();
|
||||
|
@ -158,9 +158,9 @@ class OpenSamlAuthenticationRequestResolver {
|
|||
authnRequest.setID("ARQ" + UUID.randomUUID().toString().substring(1));
|
||||
}
|
||||
String relayState = this.relayStateResolver.convert(request);
|
||||
Saml2MessageBinding binding = registration.getAssertingPartyDetails().getSingleSignOnServiceBinding();
|
||||
Saml2MessageBinding binding = registration.getAssertingPartyMetadata().getSingleSignOnServiceBinding();
|
||||
if (binding == Saml2MessageBinding.POST) {
|
||||
if (registration.getAssertingPartyDetails().getWantAuthnRequestsSigned()
|
||||
if (registration.getAssertingPartyMetadata().getWantAuthnRequestsSigned()
|
||||
|| registration.isAuthnRequestsSigned()) {
|
||||
OpenSamlSigningUtils.sign(authnRequest, registration);
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ class OpenSamlAuthenticationRequestResolver {
|
|||
.samlRequest(deflatedAndEncoded)
|
||||
.relayState(relayState)
|
||||
.id(authnRequest.getID());
|
||||
if (registration.getAssertingPartyDetails().getWantAuthnRequestsSigned()
|
||||
if (registration.getAssertingPartyMetadata().getWantAuthnRequestsSigned()
|
||||
|| registration.isAuthnRequestsSigned()) {
|
||||
OpenSamlSigningUtils.QueryParametersPartial parametersPartial = OpenSamlSigningUtils.sign(registration)
|
||||
.param(Saml2ParameterNames.SAML_REQUEST, deflatedAndEncoded);
|
||||
|
|
|
@ -95,7 +95,7 @@ final class OpenSamlSigningUtils {
|
|||
private static SignatureSigningParameters resolveSigningParameters(
|
||||
RelyingPartyRegistration relyingPartyRegistration) {
|
||||
List<Credential> credentials = resolveSigningCredentials(relyingPartyRegistration);
|
||||
List<String> algorithms = relyingPartyRegistration.getAssertingPartyDetails().getSigningAlgorithms();
|
||||
List<String> algorithms = relyingPartyRegistration.getAssertingPartyMetadata().getSigningAlgorithms();
|
||||
List<String> digests = Collections.singletonList(SignatureConstants.ALGO_ID_DIGEST_SHA256);
|
||||
String canonicalization = SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
|
||||
SignatureSigningParametersResolver resolver = new SAMLMetadataSignatureSigningParametersResolver();
|
||||
|
|
|
@ -155,12 +155,12 @@ final class OpenSamlVerificationUtils {
|
|||
|
||||
private SignatureTrustEngine trustEngine(RelyingPartyRegistration registration) {
|
||||
Set<Credential> credentials = new HashSet<>();
|
||||
Collection<Saml2X509Credential> keys = registration.getAssertingPartyDetails()
|
||||
Collection<Saml2X509Credential> keys = registration.getAssertingPartyMetadata()
|
||||
.getVerificationX509Credentials();
|
||||
for (Saml2X509Credential key : keys) {
|
||||
BasicX509Credential cred = new BasicX509Credential(key.getCertificate());
|
||||
cred.setUsageType(UsageType.SIGNING);
|
||||
cred.setEntityId(registration.getAssertingPartyDetails().getEntityId());
|
||||
cred.setEntityId(registration.getAssertingPartyMetadata().getEntityId());
|
||||
credentials.add(cred);
|
||||
}
|
||||
CredentialResolver credentialsResolver = new CollectionCredentialResolver(credentials);
|
||||
|
|
|
@ -126,13 +126,13 @@ final class OpenSamlLogoutRequestResolver {
|
|||
if (registration == null) {
|
||||
return null;
|
||||
}
|
||||
if (registration.getAssertingPartyDetails().getSingleLogoutServiceLocation() == null) {
|
||||
if (registration.getAssertingPartyMetadata().getSingleLogoutServiceLocation() == null) {
|
||||
return null;
|
||||
}
|
||||
UriResolver uriResolver = RelyingPartyRegistrationPlaceholderResolvers.uriResolver(request, registration);
|
||||
String entityId = uriResolver.resolve(registration.getEntityId());
|
||||
LogoutRequest logoutRequest = this.logoutRequestBuilder.buildObject();
|
||||
logoutRequest.setDestination(registration.getAssertingPartyDetails().getSingleLogoutServiceLocation());
|
||||
logoutRequest.setDestination(registration.getAssertingPartyMetadata().getSingleLogoutServiceLocation());
|
||||
Issuer issuer = this.issuerBuilder.buildObject();
|
||||
issuer.setValue(entityId);
|
||||
logoutRequest.setIssuer(issuer);
|
||||
|
@ -154,7 +154,7 @@ final class OpenSamlLogoutRequestResolver {
|
|||
String relayState = this.relayStateResolver.convert(request);
|
||||
Saml2LogoutRequest.Builder result = Saml2LogoutRequest.withRelyingPartyRegistration(registration)
|
||||
.id(logoutRequest.getID());
|
||||
if (registration.getAssertingPartyDetails().getSingleLogoutServiceBinding() == Saml2MessageBinding.POST) {
|
||||
if (registration.getAssertingPartyMetadata().getSingleLogoutServiceBinding() == Saml2MessageBinding.POST) {
|
||||
String xml = serialize(OpenSamlSigningUtils.sign(logoutRequest, registration));
|
||||
String samlRequest = Saml2Utils.samlEncode(xml.getBytes(StandardCharsets.UTF_8));
|
||||
return result.samlRequest(samlRequest).relayState(relayState).build();
|
||||
|
|
|
@ -143,13 +143,14 @@ final class OpenSamlLogoutResponseResolver {
|
|||
if (registration == null) {
|
||||
return null;
|
||||
}
|
||||
if (registration.getAssertingPartyDetails().getSingleLogoutServiceResponseLocation() == null) {
|
||||
if (registration.getAssertingPartyMetadata().getSingleLogoutServiceResponseLocation() == null) {
|
||||
return null;
|
||||
}
|
||||
UriResolver uriResolver = RelyingPartyRegistrationPlaceholderResolvers.uriResolver(request, registration);
|
||||
String entityId = uriResolver.resolve(registration.getEntityId());
|
||||
LogoutResponse logoutResponse = this.logoutResponseBuilder.buildObject();
|
||||
logoutResponse.setDestination(registration.getAssertingPartyDetails().getSingleLogoutServiceResponseLocation());
|
||||
logoutResponse
|
||||
.setDestination(registration.getAssertingPartyMetadata().getSingleLogoutServiceResponseLocation());
|
||||
Issuer issuer = this.issuerBuilder.buildObject();
|
||||
issuer.setValue(entityId);
|
||||
logoutResponse.setIssuer(issuer);
|
||||
|
@ -164,7 +165,7 @@ final class OpenSamlLogoutResponseResolver {
|
|||
}
|
||||
logoutResponseConsumer.accept(registration, logoutResponse);
|
||||
Saml2LogoutResponse.Builder result = Saml2LogoutResponse.withRelyingPartyRegistration(registration);
|
||||
if (registration.getAssertingPartyDetails().getSingleLogoutServiceBinding() == Saml2MessageBinding.POST) {
|
||||
if (registration.getAssertingPartyMetadata().getSingleLogoutServiceBinding() == Saml2MessageBinding.POST) {
|
||||
String xml = serialize(OpenSamlSigningUtils.sign(logoutResponse, registration));
|
||||
String samlResponse = Saml2Utils.samlEncode(xml.getBytes(StandardCharsets.UTF_8));
|
||||
result.samlResponse(samlResponse);
|
||||
|
|
|
@ -96,7 +96,7 @@ final class OpenSamlSigningUtils {
|
|||
private static SignatureSigningParameters resolveSigningParameters(
|
||||
RelyingPartyRegistration relyingPartyRegistration) {
|
||||
List<Credential> credentials = resolveSigningCredentials(relyingPartyRegistration);
|
||||
List<String> algorithms = relyingPartyRegistration.getAssertingPartyDetails().getSigningAlgorithms();
|
||||
List<String> algorithms = relyingPartyRegistration.getAssertingPartyMetadata().getSigningAlgorithms();
|
||||
List<String> digests = Collections.singletonList(SignatureConstants.ALGO_ID_DIGEST_SHA256);
|
||||
String canonicalization = SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
|
||||
SignatureSigningParametersResolver resolver = new SAMLMetadataSignatureSigningParametersResolver();
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP
|
|||
*
|
||||
* The returned logout request is suitable for sending to the asserting party based on,
|
||||
* for example, the location and binding specified in
|
||||
* {@link RelyingPartyRegistration#getAssertingPartyDetails()}.
|
||||
* {@link RelyingPartyRegistration#getAssertingPartyMetadata()}.
|
||||
*
|
||||
* @author Josh Cummings
|
||||
* @since 5.6
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.springframework.security.saml2.provider.service.registration.RelyingP
|
|||
*
|
||||
* The returned logout response is suitable for sending to the asserting party based on,
|
||||
* for example, the location and binding specified in
|
||||
* {@link RelyingPartyRegistration#getAssertingPartyDetails()}.
|
||||
* {@link RelyingPartyRegistration#getAssertingPartyMetadata()}.
|
||||
*
|
||||
* @author Josh Cummings
|
||||
* @since 5.6
|
||||
|
|
|
@ -16,13 +16,19 @@
|
|||
|
||||
package org.springframework.security.saml2.provider.service.registration;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.saml2.core.Saml2X509Credential;
|
||||
import org.springframework.security.saml2.core.TestSaml2X509Credentials;
|
||||
import org.springframework.security.saml2.provider.service.registration.RelyingPartyRegistration.AssertingPartyDetails;
|
||||
import org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
|
||||
public class RelyingPartyRegistrationTests {
|
||||
|
||||
|
@ -167,16 +173,16 @@ public class RelyingPartyRegistrationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void withAssertingPartyMetadataWhenDetailsThenBuilderCopies() {
|
||||
void withAssertingPartyMetadataWhenMetadataThenBuilderCopies() {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
||||
.nameIdFormat("format")
|
||||
.assertingPartyDetails((a) -> a.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.assertingPartyDetails((a) -> a.wantAuthnRequestsSigned(false))
|
||||
.assertingPartyDetails((a) -> a.signingAlgorithms((algs) -> algs.add("alg")))
|
||||
.assertingPartyMetadata((a) -> a.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.assertingPartyMetadata((a) -> a.wantAuthnRequestsSigned(false))
|
||||
.assertingPartyMetadata((a) -> a.signingAlgorithms((algs) -> algs.add("alg")))
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT)
|
||||
.build();
|
||||
RelyingPartyRegistration copied = RelyingPartyRegistration
|
||||
.withAssertingPartyMetadata(registration.getAssertingPartyDetails())
|
||||
.withAssertingPartyMetadata(registration.getAssertingPartyMetadata())
|
||||
.registrationId(registration.getRegistrationId())
|
||||
.entityId(registration.getEntityId())
|
||||
.signingX509Credentials((c) -> c.addAll(registration.getSigningX509Credentials()))
|
||||
|
@ -192,4 +198,160 @@ public class RelyingPartyRegistrationTests {
|
|||
compareRegistrations(registration, copied);
|
||||
}
|
||||
|
||||
@Test
|
||||
void withAssertingPartyMetadataWhenMetadataThenDisallowsDetails() {
|
||||
AssertingPartyMetadata metadata = new CustomAssertingPartyMetadata();
|
||||
assertThatExceptionOfType(IllegalArgumentException.class)
|
||||
.isThrownBy(() -> RelyingPartyRegistration.withAssertingPartyMetadata(metadata)
|
||||
.assertingPartyDetails((a) -> a.entityId("entity-id"))
|
||||
.build());
|
||||
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(
|
||||
() -> RelyingPartyRegistration.withAssertingPartyMetadata(metadata).build().getAssertingPartyDetails());
|
||||
}
|
||||
|
||||
@Test
|
||||
void withAssertingPartyMetadataWhenDetailsThenBuilderCopies() {
|
||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
||||
.nameIdFormat("format")
|
||||
.assertingPartyMetadata((a) -> a.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||
.assertingPartyMetadata((a) -> a.wantAuthnRequestsSigned(false))
|
||||
.assertingPartyMetadata((a) -> a.signingAlgorithms((algs) -> algs.add("alg")))
|
||||
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT)
|
||||
.build();
|
||||
AssertingPartyDetails details = registration.getAssertingPartyDetails();
|
||||
RelyingPartyRegistration copied = RelyingPartyRegistration.withAssertingPartyDetails(details)
|
||||
.assertingPartyDetails((a) -> a.entityId(details.getEntityId()))
|
||||
.registrationId(registration.getRegistrationId())
|
||||
.entityId(registration.getEntityId())
|
||||
.signingX509Credentials((c) -> c.addAll(registration.getSigningX509Credentials()))
|
||||
.decryptionX509Credentials((c) -> c.addAll(registration.getDecryptionX509Credentials()))
|
||||
.assertionConsumerServiceLocation(registration.getAssertionConsumerServiceLocation())
|
||||
.assertionConsumerServiceBinding(registration.getAssertionConsumerServiceBinding())
|
||||
.singleLogoutServiceLocation(registration.getSingleLogoutServiceLocation())
|
||||
.singleLogoutServiceResponseLocation(registration.getSingleLogoutServiceResponseLocation())
|
||||
.singleLogoutServiceBindings((c) -> c.addAll(registration.getSingleLogoutServiceBindings()))
|
||||
.nameIdFormat(registration.getNameIdFormat())
|
||||
.authnRequestsSigned(registration.isAuthnRequestsSigned())
|
||||
.build();
|
||||
compareRegistrations(registration, copied);
|
||||
}
|
||||
|
||||
private static class CustomAssertingPartyMetadata implements AssertingPartyMetadata {
|
||||
|
||||
@Override
|
||||
public String getEntityId() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getWantAuthnRequestsSigned() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSigningAlgorithms() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Saml2X509Credential> getVerificationX509Credentials() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Saml2X509Credential> getEncryptionX509Credentials() {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSingleSignOnServiceLocation() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Saml2MessageBinding getSingleSignOnServiceBinding() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSingleLogoutServiceLocation() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSingleLogoutServiceResponseLocation() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Saml2MessageBinding getSingleLogoutServiceBinding() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder mutate() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
private static class Builder implements AssertingPartyMetadata.Builder<Builder> {
|
||||
|
||||
@Override
|
||||
public Builder entityId(String entityId) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder wantAuthnRequestsSigned(boolean wantAuthnRequestsSigned) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder signingAlgorithms(Consumer<List<String>> signingMethodAlgorithmsConsumer) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder verificationX509Credentials(Consumer<Collection<Saml2X509Credential>> credentialsConsumer) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder encryptionX509Credentials(Consumer<Collection<Saml2X509Credential>> credentialsConsumer) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder singleSignOnServiceLocation(String singleSignOnServiceLocation) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder singleSignOnServiceBinding(Saml2MessageBinding singleSignOnServiceBinding) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder singleLogoutServiceLocation(String singleLogoutServiceLocation) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder singleLogoutServiceResponseLocation(String singleLogoutServiceResponseLocation) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Builder singleLogoutServiceBinding(Saml2MessageBinding singleLogoutServiceBinding) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssertingPartyMetadata build() {
|
||||
return new CustomAssertingPartyMetadata();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue