mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-05-30 08:42:13 +00:00
Allow Creating RelyingPartyRegistration from Metadata InputStream
Update SAML2 Login reference documentation to reflect the changes Closes gh-9558
This commit is contained in:
parent
58ebacc06f
commit
6474a9e76e
@ -536,7 +536,6 @@ RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistrations
|
|||||||
.registrationId("my-id")
|
.registrationId("my-id")
|
||||||
.build();
|
.build();
|
||||||
----
|
----
|
||||||
|
|
||||||
.Kotlin
|
.Kotlin
|
||||||
[source,kotlin,role="secondary"]
|
[source,kotlin,role="secondary"]
|
||||||
----
|
----
|
||||||
@ -547,6 +546,20 @@ val relyingPartyRegistration = RelyingPartyRegistrations
|
|||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
|
Note that you can also create a `RelyingPartyRegistration` from an arbitrary `InputStream` source.
|
||||||
|
One such example is when the metadata is stored in a database:
|
||||||
|
|
||||||
|
[source,java]
|
||||||
|
----
|
||||||
|
String xml = fromDatabase();
|
||||||
|
try (InputStream source = new ByteArrayInputStream(xml.getBytes())) {
|
||||||
|
RelyingPartyRegistration relyingPartyRegistration = RelyingPartyRegistrations
|
||||||
|
.fromMetadata(source)
|
||||||
|
.registrationId("my-id")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
Though a more sophisticated setup is also possible, like so:
|
Though a more sophisticated setup is also possible, like so:
|
||||||
|
|
||||||
====
|
====
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -28,6 +28,7 @@ import org.springframework.security.saml2.Saml2Exception;
|
|||||||
*
|
*
|
||||||
* @author Josh Cummings
|
* @author Josh Cummings
|
||||||
* @author Ryan Cassar
|
* @author Ryan Cassar
|
||||||
|
* @author Marcus da Coregio
|
||||||
* @since 5.4
|
* @since 5.4
|
||||||
*/
|
*/
|
||||||
public final class RelyingPartyRegistrations {
|
public final class RelyingPartyRegistrations {
|
||||||
@ -73,7 +74,7 @@ public final class RelyingPartyRegistrations {
|
|||||||
*/
|
*/
|
||||||
public static RelyingPartyRegistration.Builder fromMetadataLocation(String metadataLocation) {
|
public static RelyingPartyRegistration.Builder fromMetadataLocation(String metadataLocation) {
|
||||||
try (InputStream source = resourceLoader.getResource(metadataLocation).getInputStream()) {
|
try (InputStream source = resourceLoader.getResource(metadataLocation).getInputStream()) {
|
||||||
return assertingPartyMetadataConverter.convert(source);
|
return fromMetadata(source);
|
||||||
}
|
}
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
if (ex.getCause() instanceof Saml2Exception) {
|
if (ex.getCause() instanceof Saml2Exception) {
|
||||||
@ -83,4 +84,45 @@ public final class RelyingPartyRegistrations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a {@link RelyingPartyRegistration.Builder} based off of the given SAML 2.0
|
||||||
|
* Asserting Party (IDP) metadata.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* This method is intended for scenarios when the metadata is looked up by a separate
|
||||||
|
* mechanism. One such example is when the metadata is stored in a database.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* <strong>The callers of this method are accountable for closing the
|
||||||
|
* {@code InputStream} source.</strong>
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* Note that by default the registrationId is set to be the given metadata location,
|
||||||
|
* but this will most often not be sufficient. To complete the configuration, most
|
||||||
|
* applications will also need to provide a registrationId, like so:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* String xml = fromDatabase();
|
||||||
|
* try (InputStream source = new ByteArrayInputStream(xml.getBytes())) {
|
||||||
|
* RelyingPartyRegistration registration = RelyingPartyRegistrations
|
||||||
|
* .fromMetadata(source)
|
||||||
|
* .registrationId("registration-id")
|
||||||
|
* .build();
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* Also note that an {@code IDPSSODescriptor} typically only contains information
|
||||||
|
* about the asserting party. Thus, you will need to remember to still populate
|
||||||
|
* anything about the relying party, like any private keys the relying party will use
|
||||||
|
* for signing AuthnRequests.
|
||||||
|
* @param source the {@link InputStream} source containing the asserting party
|
||||||
|
* metadata
|
||||||
|
* @return the {@link RelyingPartyRegistration.Builder} for further configuration
|
||||||
|
* @since 5.6
|
||||||
|
*/
|
||||||
|
public static RelyingPartyRegistration.Builder fromMetadata(InputStream source) {
|
||||||
|
return assertingPartyMetadataConverter.convert(source);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2021 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -17,7 +17,9 @@
|
|||||||
package org.springframework.security.saml2.provider.service.registration;
|
package org.springframework.security.saml2.provider.service.registration;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -104,4 +106,27 @@ public class RelyingPartyRegistrationsTests {
|
|||||||
.isThrownBy(() -> RelyingPartyRegistrations.fromMetadataLocation("filePath"));
|
.isThrownBy(() -> RelyingPartyRegistrations.fromMetadataLocation("filePath"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromMetadataInputStreamWhenResolvableThenPopulatesBuilder() throws Exception {
|
||||||
|
try (InputStream source = new ByteArrayInputStream(this.metadata.getBytes())) {
|
||||||
|
RelyingPartyRegistration registration = RelyingPartyRegistrations.fromMetadata(source).entityId("rp")
|
||||||
|
.build();
|
||||||
|
RelyingPartyRegistration.AssertingPartyDetails details = registration.getAssertingPartyDetails();
|
||||||
|
assertThat(details.getEntityId()).isEqualTo("https://idp.example.com/idp/shibboleth");
|
||||||
|
assertThat(details.getSingleSignOnServiceLocation())
|
||||||
|
.isEqualTo("https://idp.example.com/idp/profile/SAML2/POST/SSO");
|
||||||
|
assertThat(details.getSingleSignOnServiceBinding()).isEqualTo(Saml2MessageBinding.POST);
|
||||||
|
assertThat(details.getVerificationX509Credentials()).hasSize(1);
|
||||||
|
assertThat(details.getEncryptionX509Credentials()).hasSize(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromMetadataInputStreamWhenEmptyThenSaml2Exception() throws Exception {
|
||||||
|
try (InputStream source = new ByteArrayInputStream("".getBytes())) {
|
||||||
|
assertThatExceptionOfType(Saml2Exception.class)
|
||||||
|
.isThrownBy(() -> RelyingPartyRegistrations.fromMetadata(source));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user