瀏覽代碼

Merge branch '5.8.x' into 6.0.x

Closes gh-12936
Josh Cummings 2 年之前
父節點
當前提交
20358e769d

+ 13 - 1
saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/OpenSamlAuthenticationRequestResolver.java

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 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.
@@ -30,10 +30,12 @@ import org.opensaml.core.xml.io.MarshallingException;
 import org.opensaml.saml.saml2.core.AuthnRequest;
 import org.opensaml.saml.saml2.core.AuthnRequest;
 import org.opensaml.saml.saml2.core.Issuer;
 import org.opensaml.saml.saml2.core.Issuer;
 import org.opensaml.saml.saml2.core.NameID;
 import org.opensaml.saml.saml2.core.NameID;
+import org.opensaml.saml.saml2.core.NameIDPolicy;
 import org.opensaml.saml.saml2.core.impl.AuthnRequestBuilder;
 import org.opensaml.saml.saml2.core.impl.AuthnRequestBuilder;
 import org.opensaml.saml.saml2.core.impl.AuthnRequestMarshaller;
 import org.opensaml.saml.saml2.core.impl.AuthnRequestMarshaller;
 import org.opensaml.saml.saml2.core.impl.IssuerBuilder;
 import org.opensaml.saml.saml2.core.impl.IssuerBuilder;
 import org.opensaml.saml.saml2.core.impl.NameIDBuilder;
 import org.opensaml.saml.saml2.core.impl.NameIDBuilder;
+import org.opensaml.saml.saml2.core.impl.NameIDPolicyBuilder;
 import org.w3c.dom.Element;
 import org.w3c.dom.Element;
 
 
 import org.springframework.core.convert.converter.Converter;
 import org.springframework.core.convert.converter.Converter;
@@ -69,6 +71,8 @@ class OpenSamlAuthenticationRequestResolver {
 
 
 	private final NameIDBuilder nameIdBuilder;
 	private final NameIDBuilder nameIdBuilder;
 
 
+	private final NameIDPolicyBuilder nameIdPolicyBuilder;
+
 	private RequestMatcher requestMatcher = new AntPathRequestMatcher(
 	private RequestMatcher requestMatcher = new AntPathRequestMatcher(
 			Saml2AuthenticationRequestResolver.DEFAULT_AUTHENTICATION_REQUEST_URI);
 			Saml2AuthenticationRequestResolver.DEFAULT_AUTHENTICATION_REQUEST_URI);
 
 
@@ -94,6 +98,9 @@ class OpenSamlAuthenticationRequestResolver {
 		Assert.notNull(this.issuerBuilder, "issuerBuilder must be configured in OpenSAML");
 		Assert.notNull(this.issuerBuilder, "issuerBuilder must be configured in OpenSAML");
 		this.nameIdBuilder = (NameIDBuilder) registry.getBuilderFactory().getBuilder(NameID.DEFAULT_ELEMENT_NAME);
 		this.nameIdBuilder = (NameIDBuilder) registry.getBuilderFactory().getBuilder(NameID.DEFAULT_ELEMENT_NAME);
 		Assert.notNull(this.nameIdBuilder, "nameIdBuilder must be configured in OpenSAML");
 		Assert.notNull(this.nameIdBuilder, "nameIdBuilder must be configured in OpenSAML");
+		this.nameIdPolicyBuilder = (NameIDPolicyBuilder) registry.getBuilderFactory()
+				.getBuilder(NameIDPolicy.DEFAULT_ELEMENT_NAME);
+		Assert.notNull(this.nameIdPolicyBuilder, "nameIdPolicyBuilder must be configured in OpenSAML");
 	}
 	}
 
 
 	void setRelayStateResolver(Converter<HttpServletRequest, String> relayStateResolver) {
 	void setRelayStateResolver(Converter<HttpServletRequest, String> relayStateResolver) {
@@ -129,6 +136,11 @@ class OpenSamlAuthenticationRequestResolver {
 		authnRequest.setIssuer(iss);
 		authnRequest.setIssuer(iss);
 		authnRequest.setDestination(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
 		authnRequest.setDestination(registration.getAssertingPartyDetails().getSingleSignOnServiceLocation());
 		authnRequest.setAssertionConsumerServiceURL(registration.getAssertionConsumerServiceLocation());
 		authnRequest.setAssertionConsumerServiceURL(registration.getAssertionConsumerServiceLocation());
+		if (registration.getNameIdFormat() != null) {
+			NameIDPolicy nameIdPolicy = this.nameIdPolicyBuilder.buildObject();
+			nameIdPolicy.setFormat(registration.getNameIdFormat());
+			authnRequest.setNameIDPolicy(nameIdPolicy);
+		}
 		authnRequestConsumer.accept(registration, authnRequest);
 		authnRequestConsumer.accept(registration, authnRequest);
 		if (authnRequest.getID() == null) {
 		if (authnRequest.getID() == null) {
 			authnRequest.setID("ARQ" + UUID.randomUUID().toString().substring(1));
 			authnRequest.setID("ARQ" + UUID.randomUUID().toString().substring(1));

+ 2 - 2
saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/registration/TestRelyingPartyRegistrations.java

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 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.
@@ -38,7 +38,7 @@ public final class TestRelyingPartyRegistrations {
 		Saml2X509Credential verificationCertificate = TestSaml2X509Credentials.relyingPartyVerifyingCredential();
 		Saml2X509Credential verificationCertificate = TestSaml2X509Credentials.relyingPartyVerifyingCredential();
 		String singleSignOnServiceLocation = "https://simplesaml-for-spring-saml.apps.pcfone.io/saml2/idp/SSOService.php";
 		String singleSignOnServiceLocation = "https://simplesaml-for-spring-saml.apps.pcfone.io/saml2/idp/SSOService.php";
 		String singleLogoutServiceLocation = "{baseUrl}/logout/saml2/slo";
 		String singleLogoutServiceLocation = "{baseUrl}/logout/saml2/slo";
-		return RelyingPartyRegistration.withRegistrationId(registrationId).entityId(rpEntityId)
+		return RelyingPartyRegistration.withRegistrationId(registrationId).entityId(rpEntityId).nameIdFormat("format")
 				.assertionConsumerServiceLocation(assertionConsumerServiceLocation)
 				.assertionConsumerServiceLocation(assertionConsumerServiceLocation)
 				.singleLogoutServiceLocation(singleLogoutServiceLocation)
 				.singleLogoutServiceLocation(singleLogoutServiceLocation)
 				.signingX509Credentials((c) -> c.add(signingCredential)).assertingPartyDetails(
 				.signingX509Credentials((c) -> c.add(signingCredential)).assertingPartyDetails(

+ 5 - 1
saml2/saml2-service-provider/src/test/java/org/springframework/security/saml2/provider/service/web/authentication/OpenSamlAuthenticationRequestResolverTests.java

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 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.
@@ -52,6 +52,7 @@ public class OpenSamlAuthenticationRequestResolverTests {
 		RelyingPartyRegistration registration = this.relyingPartyRegistrationBuilder.build();
 		RelyingPartyRegistration registration = this.relyingPartyRegistrationBuilder.build();
 		OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
 		OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
 		Saml2RedirectAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
 		Saml2RedirectAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
+			assertThat(authnRequest.getNameIDPolicy().getFormat()).isEqualTo(registration.getNameIdFormat());
 			assertThat(authnRequest.getAssertionConsumerServiceURL())
 			assertThat(authnRequest.getAssertionConsumerServiceURL())
 					.isEqualTo(registration.getAssertionConsumerServiceLocation());
 					.isEqualTo(registration.getAssertionConsumerServiceLocation());
 			assertThat(authnRequest.getProtocolBinding())
 			assertThat(authnRequest.getProtocolBinding())
@@ -76,6 +77,7 @@ public class OpenSamlAuthenticationRequestResolverTests {
 				.assertingPartyDetails((party) -> party.wantAuthnRequestsSigned(false)).build();
 				.assertingPartyDetails((party) -> party.wantAuthnRequestsSigned(false)).build();
 		OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
 		OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
 		Saml2RedirectAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
 		Saml2RedirectAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
+			assertThat(authnRequest.getNameIDPolicy().getFormat()).isEqualTo(registration.getNameIdFormat());
 			assertThat(authnRequest.getAssertionConsumerServiceURL())
 			assertThat(authnRequest.getAssertionConsumerServiceURL())
 					.isEqualTo(registration.getAssertionConsumerServiceLocation());
 					.isEqualTo(registration.getAssertionConsumerServiceLocation());
 			assertThat(authnRequest.getProtocolBinding())
 			assertThat(authnRequest.getProtocolBinding())
@@ -114,6 +116,7 @@ public class OpenSamlAuthenticationRequestResolverTests {
 				.build();
 				.build();
 		OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
 		OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
 		Saml2PostAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
 		Saml2PostAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
+			assertThat(authnRequest.getNameIDPolicy().getFormat()).isEqualTo(registration.getNameIdFormat());
 			assertThat(authnRequest.getAssertionConsumerServiceURL())
 			assertThat(authnRequest.getAssertionConsumerServiceURL())
 					.isEqualTo(registration.getAssertionConsumerServiceLocation());
 					.isEqualTo(registration.getAssertionConsumerServiceLocation());
 			assertThat(authnRequest.getProtocolBinding())
 			assertThat(authnRequest.getProtocolBinding())
@@ -137,6 +140,7 @@ public class OpenSamlAuthenticationRequestResolverTests {
 				.assertingPartyDetails((party) -> party.singleSignOnServiceBinding(Saml2MessageBinding.POST)).build();
 				.assertingPartyDetails((party) -> party.singleSignOnServiceBinding(Saml2MessageBinding.POST)).build();
 		OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
 		OpenSamlAuthenticationRequestResolver resolver = authenticationRequestResolver(registration);
 		Saml2PostAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
 		Saml2PostAuthenticationRequest result = resolver.resolve(request, (r, authnRequest) -> {
+			assertThat(authnRequest.getNameIDPolicy().getFormat()).isEqualTo(registration.getNameIdFormat());
 			assertThat(authnRequest.getAssertionConsumerServiceURL())
 			assertThat(authnRequest.getAssertionConsumerServiceURL())
 					.isEqualTo(registration.getAssertionConsumerServiceLocation());
 					.isEqualTo(registration.getAssertionConsumerServiceLocation());
 			assertThat(authnRequest.getProtocolBinding())
 			assertThat(authnRequest.getProtocolBinding())