|
@@ -47,6 +47,7 @@ import org.springframework.security.authentication.TestingAuthenticationToken;
|
|
import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
|
|
import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
|
|
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
|
|
import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
|
|
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
|
|
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
|
|
|
|
+import org.springframework.security.config.Customizer;
|
|
import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
|
|
import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
|
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
|
@@ -63,6 +64,7 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
|
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
|
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
|
import org.springframework.security.test.web.servlet.RequestCacheResultMatcher;
|
|
import org.springframework.security.test.web.servlet.RequestCacheResultMatcher;
|
|
import org.springframework.security.web.SecurityFilterChain;
|
|
import org.springframework.security.web.SecurityFilterChain;
|
|
|
|
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
|
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
|
|
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
|
|
import org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter;
|
|
import org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter;
|
|
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
|
|
import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
|
|
@@ -90,6 +92,8 @@ import static org.springframework.security.test.web.servlet.request.SecurityMock
|
|
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
|
|
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
|
|
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
|
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
|
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
|
|
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
|
|
|
|
+import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
|
|
|
|
+import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated;
|
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
|
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
|
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
|
@@ -365,6 +369,27 @@ public class HttpSecurityConfigurationTests {
|
|
assertThat(configSource).isInstanceOf(UrlBasedCorsConfigurationSource.class);
|
|
assertThat(configSource).isInstanceOf(UrlBasedCorsConfigurationSource.class);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Test
|
|
|
|
+ public void configureWhenAddingCustomDslUsingWithThenApplied() throws Exception {
|
|
|
|
+ this.spring.register(WithCustomDslConfig.class, UserDetailsConfig.class).autowire();
|
|
|
|
+ SecurityFilterChain filterChain = this.spring.getContext().getBean(SecurityFilterChain.class);
|
|
|
|
+ List<Filter> filters = filterChain.getFilters();
|
|
|
|
+ assertThat(filters).hasAtLeastOneElementOfType(UsernamePasswordAuthenticationFilter.class);
|
|
|
|
+ this.mockMvc.perform(formLogin()).andExpectAll(redirectedUrl("/"), authenticated());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Test
|
|
|
|
+ public void configureWhenCustomDslAddedFromFactoriesAndDisablingUsingWithThenNotApplied() throws Exception {
|
|
|
|
+ this.springFactoriesLoader.when(
|
|
|
|
+ () -> SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, getClass().getClassLoader()))
|
|
|
|
+ .thenReturn(List.of(new WithCustomDsl()));
|
|
|
|
+ this.spring.register(WithCustomDslDisabledConfig.class, UserDetailsConfig.class).autowire();
|
|
|
|
+ SecurityFilterChain filterChain = this.spring.getContext().getBean(SecurityFilterChain.class);
|
|
|
|
+ List<Filter> filters = filterChain.getFilters();
|
|
|
|
+ assertThat(filters).doesNotHaveAnyElementsOfTypes(UsernamePasswordAuthenticationFilter.class);
|
|
|
|
+ this.mockMvc.perform(formLogin()).andExpectAll(status().isNotFound(), unauthenticated());
|
|
|
|
+ }
|
|
|
|
+
|
|
@RestController
|
|
@RestController
|
|
static class NameController {
|
|
static class NameController {
|
|
|
|
|
|
@@ -661,4 +686,45 @@ public class HttpSecurityConfigurationTests {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Configuration
|
|
|
|
+ @EnableWebSecurity
|
|
|
|
+ static class WithCustomDslConfig {
|
|
|
|
+
|
|
|
|
+ @Bean
|
|
|
|
+ SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
|
|
|
+ // @formatter:off
|
|
|
|
+ http
|
|
|
|
+ .with(new WithCustomDsl(), Customizer.withDefaults())
|
|
|
|
+ .httpBasic(Customizer.withDefaults());
|
|
|
|
+ // @formatter:on
|
|
|
|
+ return http.build();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Configuration
|
|
|
|
+ @EnableWebSecurity
|
|
|
|
+ static class WithCustomDslDisabledConfig {
|
|
|
|
+
|
|
|
|
+ @Bean
|
|
|
|
+ SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
|
|
|
+ // @formatter:off
|
|
|
|
+ http
|
|
|
|
+ .with(new WithCustomDsl(), (dsl) -> dsl.disable())
|
|
|
|
+ .httpBasic(Customizer.withDefaults());
|
|
|
|
+ // @formatter:on
|
|
|
|
+ return http.build();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ static class WithCustomDsl extends AbstractHttpConfigurer<WithCustomDsl, HttpSecurity> {
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void init(HttpSecurity builder) throws Exception {
|
|
|
|
+ builder.formLogin(Customizer.withDefaults());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|