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