Browse Source

add SAML authentication request support to login configurer

Closes gh-8873
Houssem BELHADJ AHMED 3 năm trước cách đây
mục cha
commit
f4049c18b1

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

@@ -109,7 +109,7 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
 
 	private String loginPage;
 
-	private String authenticationRequestUri = "/saml2/authenticate/{registrationId}";
+	private String authenticationRequestUri = Saml2AuthenticationRequestResolver.DEFAULT_AUTHENTICATION_REQUEST_URI;
 
 	private Saml2AuthenticationRequestResolver authenticationRequestResolver;
 
@@ -186,6 +186,24 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
 		return this;
 	}
 
+	/**
+	 * Customize the URL that the SAML Authentication Request will be sent to.
+	 * @param authenticationRequestUri the URI to use for the SAML 2.0 Authentication
+	 * Request
+	 * @return the {@link Saml2LoginConfigurer} for further configuration
+	 * @since 6.0
+	 */
+	public Saml2LoginConfigurer<B> authenticationRequestUri(String authenticationRequestUri) {
+		// OpenSAML 3 is no longer supported by spring security
+		if (version().startsWith("3")) {
+			return this;
+		}
+		Assert.state(authenticationRequestUri.contains("{registrationId}"),
+				"authenticationRequestUri must contain {registrationId} path variable");
+		this.authenticationRequestUri = authenticationRequestUri;
+		return this;
+	}
+
 	/**
 	 * Specifies the URL to validate the credentials. If specified a custom URL, consider
 	 * specifying a custom {@link AuthenticationConverter} via
@@ -307,7 +325,11 @@ public final class Saml2LoginConfigurer<B extends HttpSecurityBuilder<B>>
 			return bean;
 		}
 		if (version().startsWith("4")) {
-			return new OpenSaml4AuthenticationRequestResolver(relyingPartyRegistrationResolver(http));
+			OpenSaml4AuthenticationRequestResolver openSaml4AuthenticationRequestResolver = new OpenSaml4AuthenticationRequestResolver(
+					relyingPartyRegistrationResolver(http));
+			openSaml4AuthenticationRequestResolver
+					.setRequestMatcher(new AntPathRequestMatcher(this.authenticationRequestUri));
+			return openSaml4AuthenticationRequestResolver;
 		}
 		return new OpenSaml3AuthenticationRequestResolver(relyingPartyRegistrationResolver(http));
 	}

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

@@ -297,6 +297,17 @@ public class Saml2LoginConfigurerTests {
 		verify(repository).removeAuthenticationRequest(any(HttpServletRequest.class), any(HttpServletResponse.class));
 	}
 
+	@Test
+	public void authenticationRequestWhenCustomAuthenticationRequestUriRepositoryThenUses() throws Exception {
+		this.spring.register(CustomAuthenticationRequestUriCustomAuthenticationConverter.class).autowire();
+		MockHttpServletRequestBuilder request = get("/custom/auth/registration-id");
+		this.mvc.perform(request).andExpect(status().isFound());
+		Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> repository = this.spring.getContext()
+				.getBean(Saml2AuthenticationRequestRepository.class);
+		verify(repository).saveAuthenticationRequest(any(AbstractSaml2AuthenticationRequest.class),
+				any(HttpServletRequest.class), any(HttpServletResponse.class));
+	}
+
 	@Test
 	public void saml2LoginWhenLoginProcessingUrlWithoutRegistrationIdAndDefaultAuthenticationConverterThenValidates() {
 		assertThatExceptionOfType(BeanCreationException.class)
@@ -601,6 +612,30 @@ public class Saml2LoginConfigurerTests {
 
 	}
 
+	@EnableWebSecurity
+	@Import(Saml2LoginConfigBeans.class)
+	static class CustomAuthenticationRequestUriCustomAuthenticationConverter {
+
+		private final Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> repository = mock(
+				Saml2AuthenticationRequestRepository.class);
+
+		@Bean
+		Saml2AuthenticationRequestRepository<AbstractSaml2AuthenticationRequest> authenticationRequestRepository() {
+			return this.repository;
+		}
+
+		@Bean
+		SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+			// @formatter:off
+			http
+				.authorizeRequests((authz) -> authz.anyRequest().authenticated())
+				.saml2Login((saml2) -> saml2.authenticationRequestUri("/custom/auth/{registrationId}"));
+			// @formatter:on
+			return http.build();
+		}
+
+	}
+
 	@EnableWebSecurity
 	@Import(Saml2LoginConfigBeans.class)
 	static class CustomLoginProcessingUrlCustomAuthenticationConverter {

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

@@ -59,9 +59,6 @@ class OpenSamlAuthenticationRequestResolver {
 	static {
 		OpenSamlInitializationService.initialize();
 	}
-
-	private final RequestMatcher requestMatcher = new AntPathRequestMatcher("/saml2/authenticate/{registrationId}");
-
 	private final RelyingPartyRegistrationResolver relyingPartyRegistrationResolver;
 
 	private final AuthnRequestBuilder authnRequestBuilder;
@@ -72,6 +69,9 @@ class OpenSamlAuthenticationRequestResolver {
 
 	private final NameIDBuilder nameIdBuilder;
 
+	private RequestMatcher requestMatcher = new AntPathRequestMatcher(
+			Saml2AuthenticationRequestResolver.DEFAULT_AUTHENTICATION_REQUEST_URI);
+
 	private Converter<HttpServletRequest, String> relayStateResolver = (request) -> UUID.randomUUID().toString();
 
 	/**

+ 2 - 0
saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/Saml2AuthenticationRequestResolver.java

@@ -29,6 +29,8 @@ import org.springframework.security.saml2.provider.service.authentication.Abstra
  */
 public interface Saml2AuthenticationRequestResolver {
 
+	String DEFAULT_AUTHENTICATION_REQUEST_URI = "/saml2/authenticate/{registrationId}";
+
 	<T extends AbstractSaml2AuthenticationRequest> T resolve(HttpServletRequest request);
 
 }