Polish Signature Algorithm Support
- Changed name to signatureAlgorithms since method and algorithm are synonymous - Re-ordered methods to follow typical IDPSSODescriptor order - Adjusted JavaDoc to refer to IDPSSODescriptor terminology Issue gh-8952
This commit is contained in:
parent
9900658c92
commit
e1826a0bd8
|
@ -274,7 +274,7 @@ public class OpenSamlAuthenticationRequestFactory implements Saml2Authentication
|
||||||
|
|
||||||
private SignatureSigningParameters resolveSigningParameters(RelyingPartyRegistration relyingPartyRegistration) {
|
private SignatureSigningParameters resolveSigningParameters(RelyingPartyRegistration relyingPartyRegistration) {
|
||||||
List<Credential> credentials = resolveSigningCredentials(relyingPartyRegistration);
|
List<Credential> credentials = resolveSigningCredentials(relyingPartyRegistration);
|
||||||
List<String> algorithms = relyingPartyRegistration.getAssertingPartyDetails().getSigningMethodAlgorithms();
|
List<String> algorithms = relyingPartyRegistration.getAssertingPartyDetails().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();
|
||||||
|
|
|
@ -19,7 +19,6 @@ package org.springframework.security.saml2.provider.service.registration;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -368,6 +367,8 @@ public final class RelyingPartyRegistration {
|
||||||
.assertingPartyDetails((assertingParty) -> assertingParty
|
.assertingPartyDetails((assertingParty) -> assertingParty
|
||||||
.entityId(registration.getAssertingPartyDetails().getEntityId())
|
.entityId(registration.getAssertingPartyDetails().getEntityId())
|
||||||
.wantAuthnRequestsSigned(registration.getAssertingPartyDetails().getWantAuthnRequestsSigned())
|
.wantAuthnRequestsSigned(registration.getAssertingPartyDetails().getWantAuthnRequestsSigned())
|
||||||
|
.signingAlgorithms((algorithms) -> algorithms
|
||||||
|
.addAll(registration.getAssertingPartyDetails().getSigningAlgorithms()))
|
||||||
.verificationX509Credentials((c) -> c
|
.verificationX509Credentials((c) -> c
|
||||||
.addAll(registration.getAssertingPartyDetails().getVerificationX509Credentials()))
|
.addAll(registration.getAssertingPartyDetails().getVerificationX509Credentials()))
|
||||||
.encryptionX509Credentials(
|
.encryptionX509Credentials(
|
||||||
|
@ -434,6 +435,8 @@ public final class RelyingPartyRegistration {
|
||||||
|
|
||||||
private final boolean wantAuthnRequestsSigned;
|
private final boolean wantAuthnRequestsSigned;
|
||||||
|
|
||||||
|
private List<String> signingAlgorithms;
|
||||||
|
|
||||||
private final Collection<Saml2X509Credential> verificationX509Credentials;
|
private final Collection<Saml2X509Credential> verificationX509Credentials;
|
||||||
|
|
||||||
private final Collection<Saml2X509Credential> encryptionX509Credentials;
|
private final Collection<Saml2X509Credential> encryptionX509Credentials;
|
||||||
|
@ -442,13 +445,12 @@ public final class RelyingPartyRegistration {
|
||||||
|
|
||||||
private final Saml2MessageBinding singleSignOnServiceBinding;
|
private final Saml2MessageBinding singleSignOnServiceBinding;
|
||||||
|
|
||||||
private List<String> signingMethodAlgorithms;
|
private AssertingPartyDetails(String entityId, boolean wantAuthnRequestsSigned, List<String> signingAlgorithms,
|
||||||
|
|
||||||
private AssertingPartyDetails(String entityId, boolean wantAuthnRequestsSigned,
|
|
||||||
Collection<Saml2X509Credential> verificationX509Credentials,
|
Collection<Saml2X509Credential> verificationX509Credentials,
|
||||||
Collection<Saml2X509Credential> encryptionX509Credentials, String singleSignOnServiceLocation,
|
Collection<Saml2X509Credential> encryptionX509Credentials, String singleSignOnServiceLocation,
|
||||||
Saml2MessageBinding singleSignOnServiceBinding, List<String> signingMethodAlgorithms) {
|
Saml2MessageBinding singleSignOnServiceBinding) {
|
||||||
Assert.hasText(entityId, "entityId cannot be null or empty");
|
Assert.hasText(entityId, "entityId cannot be null or empty");
|
||||||
|
Assert.notEmpty(signingAlgorithms, "signingAlgorithms cannot be empty");
|
||||||
Assert.notNull(verificationX509Credentials, "verificationX509Credentials cannot be null");
|
Assert.notNull(verificationX509Credentials, "verificationX509Credentials cannot be null");
|
||||||
for (Saml2X509Credential credential : verificationX509Credentials) {
|
for (Saml2X509Credential credential : verificationX509Credentials) {
|
||||||
Assert.notNull(credential, "verificationX509Credentials cannot have null values");
|
Assert.notNull(credential, "verificationX509Credentials cannot have null values");
|
||||||
|
@ -463,14 +465,13 @@ public final class RelyingPartyRegistration {
|
||||||
}
|
}
|
||||||
Assert.notNull(singleSignOnServiceLocation, "singleSignOnServiceLocation cannot be null");
|
Assert.notNull(singleSignOnServiceLocation, "singleSignOnServiceLocation cannot be null");
|
||||||
Assert.notNull(singleSignOnServiceBinding, "singleSignOnServiceBinding cannot be null");
|
Assert.notNull(singleSignOnServiceBinding, "singleSignOnServiceBinding cannot be null");
|
||||||
Assert.notEmpty(signingMethodAlgorithms, "signingMethodAlgorithms cannot be empty");
|
|
||||||
this.entityId = entityId;
|
this.entityId = entityId;
|
||||||
this.wantAuthnRequestsSigned = wantAuthnRequestsSigned;
|
this.wantAuthnRequestsSigned = wantAuthnRequestsSigned;
|
||||||
|
this.signingAlgorithms = signingAlgorithms;
|
||||||
this.verificationX509Credentials = verificationX509Credentials;
|
this.verificationX509Credentials = verificationX509Credentials;
|
||||||
this.encryptionX509Credentials = encryptionX509Credentials;
|
this.encryptionX509Credentials = encryptionX509Credentials;
|
||||||
this.singleSignOnServiceLocation = singleSignOnServiceLocation;
|
this.singleSignOnServiceLocation = singleSignOnServiceLocation;
|
||||||
this.singleSignOnServiceBinding = singleSignOnServiceBinding;
|
this.singleSignOnServiceBinding = singleSignOnServiceBinding;
|
||||||
this.signingMethodAlgorithms = signingMethodAlgorithms;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -500,6 +501,20 @@ public final class RelyingPartyRegistration {
|
||||||
return this.wantAuthnRequestsSigned;
|
return this.wantAuthnRequestsSigned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of org.opensaml.saml.ext.saml2alg.SigningMethod Algorithms for
|
||||||
|
* this asserting party, in preference order.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Equivalent to the values found in <SigningMethod Algorithm="..."/> in the
|
||||||
|
* asserting party's <IDPSSODescriptor>.
|
||||||
|
* @return the list of SigningMethod Algorithms
|
||||||
|
* @since 5.5
|
||||||
|
*/
|
||||||
|
public List<String> getSigningAlgorithms() {
|
||||||
|
return this.signingAlgorithms;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all verification {@link Saml2X509Credential}s associated with this
|
* Get all verification {@link Saml2X509Credential}s associated with this
|
||||||
* asserting party
|
* asserting party
|
||||||
|
@ -550,21 +565,14 @@ public final class RelyingPartyRegistration {
|
||||||
return this.singleSignOnServiceBinding;
|
return this.singleSignOnServiceBinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the list of preferred signature algorithm URIs, in preference order.
|
|
||||||
* @return the list of signature algorithm URIs
|
|
||||||
* @since 5.5
|
|
||||||
*/
|
|
||||||
public List<String> getSigningMethodAlgorithms() {
|
|
||||||
return this.signingMethodAlgorithms;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class Builder {
|
public static final class Builder {
|
||||||
|
|
||||||
private String entityId;
|
private String entityId;
|
||||||
|
|
||||||
private boolean wantAuthnRequestsSigned = true;
|
private boolean wantAuthnRequestsSigned = true;
|
||||||
|
|
||||||
|
private List<String> signingAlgorithms = new ArrayList<>();
|
||||||
|
|
||||||
private Collection<Saml2X509Credential> verificationX509Credentials = new HashSet<>();
|
private Collection<Saml2X509Credential> verificationX509Credentials = new HashSet<>();
|
||||||
|
|
||||||
private Collection<Saml2X509Credential> encryptionX509Credentials = new HashSet<>();
|
private Collection<Saml2X509Credential> encryptionX509Credentials = new HashSet<>();
|
||||||
|
@ -573,8 +581,6 @@ public final class RelyingPartyRegistration {
|
||||||
|
|
||||||
private Saml2MessageBinding singleSignOnServiceBinding = Saml2MessageBinding.REDIRECT;
|
private Saml2MessageBinding singleSignOnServiceBinding = Saml2MessageBinding.REDIRECT;
|
||||||
|
|
||||||
private List<String> signingMethodAlgorithms = new ArrayList<>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the asserting party's <a href=
|
* Set the asserting party's <a href=
|
||||||
* "https://wiki.shibboleth.net/confluence/display/CONCEPT/EntityNaming">EntityID</a>.
|
* "https://wiki.shibboleth.net/confluence/display/CONCEPT/EntityNaming">EntityID</a>.
|
||||||
|
@ -600,6 +606,19 @@ public final class RelyingPartyRegistration {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply this {@link Consumer} to the list of SigningMethod Algorithms
|
||||||
|
* @param signingMethodAlgorithmsConsumer a {@link Consumer} of the list of
|
||||||
|
* SigningMethod Algorithms
|
||||||
|
* @return this {@link AssertingPartyDetails.Builder} for further
|
||||||
|
* configuration
|
||||||
|
* @since 5.5
|
||||||
|
*/
|
||||||
|
public Builder signingAlgorithms(Consumer<List<String>> signingMethodAlgorithmsConsumer) {
|
||||||
|
signingMethodAlgorithmsConsumer.accept(this.signingAlgorithms);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply this {@link Consumer} to the list of {@link Saml2X509Credential}s
|
* Apply this {@link Consumer} to the list of {@link Saml2X509Credential}s
|
||||||
* @param credentialsConsumer a {@link Consumer} of the {@link List} of
|
* @param credentialsConsumer a {@link Consumer} of the {@link List} of
|
||||||
|
@ -658,31 +677,19 @@ public final class RelyingPartyRegistration {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply this {@link Consumer} to the list of signature algorithm URIs
|
|
||||||
* @param signingMethodAlgorithmsConsumer a {@link Consumer} of the list of
|
|
||||||
* signature algorithm URIs
|
|
||||||
* @return this {@code Builder}
|
|
||||||
* @since 5.5
|
|
||||||
*/
|
|
||||||
public Builder signingMethodAlgorithms(Consumer<List<String>> signingMethodAlgorithmsConsumer) {
|
|
||||||
signingMethodAlgorithmsConsumer.accept(this.signingMethodAlgorithms);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an immutable ProviderDetails object representing the configuration
|
* Creates an immutable ProviderDetails object representing the configuration
|
||||||
* for an Identity Provider, IDP
|
* for an Identity Provider, IDP
|
||||||
* @return immutable ProviderDetails object
|
* @return immutable ProviderDetails object
|
||||||
*/
|
*/
|
||||||
public AssertingPartyDetails build() {
|
public AssertingPartyDetails build() {
|
||||||
List<String> signingMethodAlgorithmsCopy = this.signingMethodAlgorithms.isEmpty()
|
List<String> signingAlgorithms = this.signingAlgorithms.isEmpty()
|
||||||
? Arrays.asList(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256)
|
? Collections.singletonList(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256)
|
||||||
: Collections.unmodifiableList(this.signingMethodAlgorithms);
|
: Collections.unmodifiableList(this.signingAlgorithms);
|
||||||
|
|
||||||
return new AssertingPartyDetails(this.entityId, this.wantAuthnRequestsSigned,
|
return new AssertingPartyDetails(this.entityId, this.wantAuthnRequestsSigned, signingAlgorithms,
|
||||||
this.verificationX509Credentials, this.encryptionX509Credentials,
|
this.verificationX509Credentials, this.encryptionX509Credentials,
|
||||||
this.singleSignOnServiceLocation, this.singleSignOnServiceBinding, signingMethodAlgorithmsCopy);
|
this.singleSignOnServiceLocation, this.singleSignOnServiceBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,7 @@ public class OpenSamlAuthenticationRequestFactoryTests {
|
||||||
public void createRedirectAuthenticationRequestWhenSHA1SignRequestThenSignatureIsPresent() {
|
public void createRedirectAuthenticationRequestWhenSHA1SignRequestThenSignatureIsPresent() {
|
||||||
RelyingPartyRegistration relyingPartyRegistration = this.relyingPartyRegistrationBuilder
|
RelyingPartyRegistration relyingPartyRegistration = this.relyingPartyRegistrationBuilder
|
||||||
.assertingPartyDetails(
|
.assertingPartyDetails(
|
||||||
(a) -> a.signingMethodAlgorithms((c) -> c.add(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1)))
|
(a) -> a.signingAlgorithms((algs) -> algs.add(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1)))
|
||||||
.build();
|
.build();
|
||||||
Saml2AuthenticationRequestContext context = this.contextBuilder.relayState("Relay State Value")
|
Saml2AuthenticationRequestContext context = this.contextBuilder.relayState("Relay State Value")
|
||||||
.relyingPartyRegistration(relyingPartyRegistration).build();
|
.relyingPartyRegistration(relyingPartyRegistration).build();
|
||||||
|
|
|
@ -28,8 +28,9 @@ public class RelyingPartyRegistrationTests {
|
||||||
@Test
|
@Test
|
||||||
public void withRelyingPartyRegistrationWorks() {
|
public void withRelyingPartyRegistrationWorks() {
|
||||||
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
RelyingPartyRegistration registration = TestRelyingPartyRegistrations.relyingPartyRegistration()
|
||||||
.providerDetails((p) -> p.binding(Saml2MessageBinding.POST))
|
.assertingPartyDetails((a) -> a.singleSignOnServiceBinding(Saml2MessageBinding.POST))
|
||||||
.providerDetails((p) -> p.signAuthNRequest(false))
|
.assertingPartyDetails((a) -> a.wantAuthnRequestsSigned(false))
|
||||||
|
.assertingPartyDetails((a) -> a.signingAlgorithms((algs) -> algs.add("alg")))
|
||||||
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT).build();
|
.assertionConsumerServiceBinding(Saml2MessageBinding.REDIRECT).build();
|
||||||
RelyingPartyRegistration copy = RelyingPartyRegistration.withRelyingPartyRegistration(registration).build();
|
RelyingPartyRegistration copy = RelyingPartyRegistration.withRelyingPartyRegistration(registration).build();
|
||||||
compareRegistrations(registration, copy);
|
compareRegistrations(registration, copy);
|
||||||
|
@ -71,6 +72,8 @@ public class RelyingPartyRegistrationTests {
|
||||||
.isEqualTo(registration.getAssertingPartyDetails().getEncryptionX509Credentials());
|
.isEqualTo(registration.getAssertingPartyDetails().getEncryptionX509Credentials());
|
||||||
assertThat(copy.getAssertingPartyDetails().getVerificationX509Credentials())
|
assertThat(copy.getAssertingPartyDetails().getVerificationX509Credentials())
|
||||||
.isEqualTo(registration.getAssertingPartyDetails().getVerificationX509Credentials());
|
.isEqualTo(registration.getAssertingPartyDetails().getVerificationX509Credentials());
|
||||||
|
assertThat(copy.getAssertingPartyDetails().getSigningAlgorithms())
|
||||||
|
.isEqualTo(registration.getAssertingPartyDetails().getSigningAlgorithms());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue