瀏覽代碼

Update Saml2LoginConfigurer to pick up Saml2AuthenticationTokenConverter bean

Closes gh-10268
Marcus Da Coregio 3 年之前
父節點
當前提交
0364518b69

+ 7 - 2
config/src/main/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LoginConfigurer.java

@@ -268,12 +268,17 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
 	}
 
 	private AuthenticationConverter getAuthenticationConverter(B http) {
-		if (this.authenticationConverter == null) {
+		if (this.authenticationConverter != null) {
+			return this.authenticationConverter;
+		}
+		AuthenticationConverter authenticationConverterBean = getBeanOrNull(http,
+				Saml2AuthenticationTokenConverter.class);
+		if (authenticationConverterBean == null) {
 			return new Saml2AuthenticationTokenConverter(
 					(RelyingPartyRegistrationResolver) new DefaultRelyingPartyRegistrationResolver(
 							this.relyingPartyRegistrationRepository));
 		}
-		return this.authenticationConverter;
+		return authenticationConverterBean;
 	}
 
 	private String version() {

+ 43 - 0
config/src/test/java/org/springframework/security/config/annotation/web/configurers/saml2/Saml2LoginConfigurerTests.java

@@ -49,6 +49,7 @@ import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.AuthenticationProvider;
 import org.springframework.security.authentication.AuthenticationServiceException;
 import org.springframework.security.authentication.ProviderManager;
+import org.springframework.security.config.Customizer;
 import org.springframework.security.config.annotation.ObjectPostProcessor;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
@@ -80,6 +81,7 @@ import org.springframework.security.saml2.provider.service.registration.TestRely
 import org.springframework.security.saml2.provider.service.servlet.Saml2AuthenticationRequestRepository;
 import org.springframework.security.saml2.provider.service.servlet.filter.Saml2WebSsoAuthenticationFilter;
 import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationRequestContextResolver;
+import org.springframework.security.saml2.provider.service.web.Saml2AuthenticationTokenConverter;
 import org.springframework.security.web.FilterChainProxy;
 import org.springframework.security.web.SecurityFilterChain;
 import org.springframework.security.web.authentication.AuthenticationConverter;
@@ -223,6 +225,26 @@ public class Saml2LoginConfigurerTests {
 		verify(CustomAuthenticationConverter.authenticationConverter).convert(any(HttpServletRequest.class));
 	}
 
+	@Test
+	public void authenticateWhenCustomAuthenticationConverterBeanThenUses() throws Exception {
+		this.spring.register(CustomAuthenticationConverterBean.class).autowire();
+		Saml2AuthenticationTokenConverter authenticationConverter = this.spring.getContext()
+				.getBean(Saml2AuthenticationTokenConverter.class);
+		RelyingPartyRegistration relyingPartyRegistration = TestRelyingPartyRegistrations.noCredentials()
+				.assertingPartyDetails((party) -> party.verificationX509Credentials(
+						(c) -> c.add(TestSaml2X509Credentials.relyingPartyVerifyingCredential())))
+				.build();
+		String response = new String(Saml2Utils.samlDecode(SIGNED_RESPONSE));
+		given(authenticationConverter.convert(any(HttpServletRequest.class)))
+				.willReturn(new Saml2AuthenticationToken(relyingPartyRegistration, response));
+		// @formatter:off
+		MockHttpServletRequestBuilder request = post("/login/saml2/sso/" + relyingPartyRegistration.getRegistrationId())
+				.param("SAMLResponse", SIGNED_RESPONSE);
+		// @formatter:on
+		this.mvc.perform(request).andExpect(redirectedUrl("/"));
+		verify(authenticationConverter).convert(any(HttpServletRequest.class));
+	}
+
 	@Test
 	public void authenticateWithInvalidDeflatedSAMLResponseThenFailureHandlerUses() throws Exception {
 		this.spring.register(CustomAuthenticationFailureHandler.class).autowire();
@@ -447,6 +469,27 @@ public class Saml2LoginConfigurerTests {
 
 	}
 
+	@EnableWebSecurity
+	@Import(Saml2LoginConfigBeans.class)
+	static class CustomAuthenticationConverterBean {
+
+		private final Saml2AuthenticationTokenConverter authenticationConverter = mock(
+				Saml2AuthenticationTokenConverter.class);
+
+		@Bean
+		SecurityFilterChain app(HttpSecurity http) throws Exception {
+			http.authorizeHttpRequests((authz) -> authz.anyRequest().authenticated())
+					.saml2Login(Customizer.withDefaults());
+			return http.build();
+		}
+
+		@Bean
+		Saml2AuthenticationTokenConverter authenticationConverter() {
+			return this.authenticationConverter;
+		}
+
+	}
+
 	@EnableWebSecurity
 	@Import(Saml2LoginConfigBeans.class)
 	static class CustomAuthenticationRequestRepository {