Add OpenSamlAssertingPartyMetadataRepository
Closes gh-12116 Closes gh-15395
This commit is contained in:
@@ -27,11 +27,130 @@ Kotlin::
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
val details: OpenSamlAssertingPartyDetails =
|
||||
registration.getAssertingPartyDetails() as OpenSamlAssertingPartyDetails;
|
||||
val openSamlEntityDescriptor: EntityDescriptor = details.getEntityDescriptor();
|
||||
registration.getAssertingPartyDetails() as OpenSamlAssertingPartyDetails
|
||||
val openSamlEntityDescriptor: EntityDescriptor = details.getEntityDescriptor()
|
||||
----
|
||||
======
|
||||
|
||||
=== Using `AssertingPartyMetadataRepository`
|
||||
|
||||
You can also be more targeted than `RelyingPartyRegistrations` by using `AssertingPartyMetadataRepository`, an interface that allows for only retrieving the asserting party metadata.
|
||||
|
||||
This allows three valuable features:
|
||||
|
||||
* Implementations can refresh asserting party metadata in an expiry-aware fashion
|
||||
* Implementations of `RelyingPartyRegistrationRepository` can more easily articulate a relationship between a relying party and its one or many corresponding asserting parties
|
||||
* Implementations can verify metadata signatures
|
||||
|
||||
For example, `OpenSamlAssertingPartyMetadataRepository` uses OpenSAML's `MetadataResolver`, and API whose implementations regularly refresh the underlying metadata in an expiry-aware fashion.
|
||||
|
||||
This means that you can now create a refreshable `RelyingPartyRegistrationRepository` in just a few lines of code:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
@Component
|
||||
public class RefreshableRelyingPartyRegistrationRepository
|
||||
implements IterableRelyingPartyRegistrationRepository {
|
||||
|
||||
private final AssertingPartyMetadataRepository metadata =
|
||||
OpenSamlAssertingPartyMetadataRepository
|
||||
.fromTrustedMetadataLocation("https://idp.example.org/metadata").build();
|
||||
|
||||
@Override
|
||||
public RelyingPartyRegistration findByRegistrationId(String registrationId) {
|
||||
AssertingPartyMetadata metadata = this.metadata.findByEntityId(registrationId);
|
||||
if (metadata == null) {
|
||||
return null;
|
||||
}
|
||||
return applyRelyingParty(metadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<RelyingPartyRegistration> iterator() {
|
||||
return StreamSupport.stream(this.metadata.spliterator(), false)
|
||||
.map(this::applyRelyingParty).iterator();
|
||||
}
|
||||
|
||||
private RelyingPartyRegistration applyRelyingParty(AssertingPartyMetadata metadata) {
|
||||
AssertingPartyDetails details = (AssertingPartyDetails) metadata;
|
||||
return RelyingPartyRegistration.withAssertingPartyDetails(details)
|
||||
// apply any relying party configuration
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
@Component
|
||||
class RefreshableRelyingPartyRegistrationRepository : IterableRelyingPartyRegistrationRepository {
|
||||
|
||||
private val metadata: AssertingPartyMetadataRepository =
|
||||
OpenSamlAssertingPartyMetadataRepository.fromTrustedMetadataLocation(
|
||||
"https://idp.example.org/metadata").build()
|
||||
|
||||
fun findByRegistrationId(registrationId:String?): RelyingPartyRegistration {
|
||||
val metadata = this.metadata.findByEntityId(registrationId)
|
||||
if (metadata == null) {
|
||||
return null
|
||||
}
|
||||
return applyRelyingParty(metadata)
|
||||
}
|
||||
|
||||
fun iterator(): Iterator<RelyingPartyRegistration> {
|
||||
return StreamSupport.stream(this.metadata.spliterator(), false)
|
||||
.map(this::applyRelyingParty).iterator()
|
||||
}
|
||||
|
||||
private fun applyRelyingParty(metadata: AssertingPartyMetadata): RelyingPartyRegistration {
|
||||
val details: AssertingPartyDetails = metadata as AssertingPartyDetails
|
||||
return RelyingPartyRegistration.withAssertingPartyDetails(details)
|
||||
// apply any relying party configuration
|
||||
.build()
|
||||
}
|
||||
}
|
||||
----
|
||||
======
|
||||
|
||||
[TIP]
|
||||
`OpenSamlAssertingPartyMetadataRepository` also ships with a constructor so you can provide a custom `MetadataResolver`. Since the underlying `MetadataResolver` is doing the expirying and refreshing, if you use the constructor directly, you will only get these features by providing an implementation that does so.
|
||||
|
||||
=== Verifying Metadata Signatures
|
||||
|
||||
You can also verify metadata signatures using `OpenSamlAssertingPartyMetadataRepository` by providing the appropriate set of ``Saml2X509Credential``s as follows:
|
||||
|
||||
[tabs]
|
||||
======
|
||||
Java::
|
||||
+
|
||||
[source,java,role="primary"]
|
||||
----
|
||||
OpenSamlAssertingPartyMetadataRepository.withMetadataLocation("https://idp.example.org/metadata")
|
||||
.verificationCredentials((c) -> c.add(myVerificationCredential))
|
||||
.build();
|
||||
----
|
||||
|
||||
Kotlin::
|
||||
+
|
||||
[source,kotlin,role="secondary"]
|
||||
----
|
||||
OpenSamlAssertingPartyMetadataRepository.withMetadataLocation("https://idp.example.org/metadata")
|
||||
.verificationCredentials({ c : Collection<Saml2X509Credential> ->
|
||||
c.add(myVerificationCredential) })
|
||||
.build()
|
||||
----
|
||||
======
|
||||
|
||||
[NOTE]
|
||||
If no credentials are provided, the component will not perform signature validation.
|
||||
|
||||
[[publishing-relying-party-metadata]]
|
||||
== Producing `<saml2:SPSSODescriptor>` Metadata
|
||||
|
||||
|
||||
Reference in New Issue
Block a user