|
47 | 47 | import org.springframework.security.authentication.event.AbstractAuthenticationEvent;
|
48 | 48 | import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent;
|
49 | 49 | import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
|
| 50 | +import org.springframework.security.config.Customizer; |
50 | 51 | import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
|
51 | 52 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
52 | 53 | import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
|
63 | 64 | import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
64 | 65 | import org.springframework.security.test.web.servlet.RequestCacheResultMatcher;
|
65 | 66 | import org.springframework.security.web.SecurityFilterChain;
|
| 67 | +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; |
66 | 68 | import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
|
67 | 69 | import org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter;
|
68 | 70 | import org.springframework.security.web.header.writers.frameoptions.XFrameOptionsHeaderWriter;
|
|
90 | 92 | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.authentication;
|
91 | 93 | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
92 | 94 | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
|
| 95 | +import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated; |
| 96 | +import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated; |
93 | 97 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
|
94 | 98 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
95 | 99 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
@@ -365,6 +369,27 @@ public void configureWhenCorsConfigurationSourceThenApplyCors() {
|
365 | 369 | assertThat(configSource).isInstanceOf(UrlBasedCorsConfigurationSource.class);
|
366 | 370 | }
|
367 | 371 |
|
| 372 | + @Test |
| 373 | + public void configureWhenAddingCustomDslUsingWithThenApplied() throws Exception { |
| 374 | + this.spring.register(WithCustomDslConfig.class, UserDetailsConfig.class).autowire(); |
| 375 | + SecurityFilterChain filterChain = this.spring.getContext().getBean(SecurityFilterChain.class); |
| 376 | + List<Filter> filters = filterChain.getFilters(); |
| 377 | + assertThat(filters).hasAtLeastOneElementOfType(UsernamePasswordAuthenticationFilter.class); |
| 378 | + this.mockMvc.perform(formLogin()).andExpectAll(redirectedUrl("/"), authenticated()); |
| 379 | + } |
| 380 | + |
| 381 | + @Test |
| 382 | + public void configureWhenCustomDslAddedFromFactoriesAndDisablingUsingWithThenNotApplied() throws Exception { |
| 383 | + this.springFactoriesLoader.when( |
| 384 | + () -> SpringFactoriesLoader.loadFactories(AbstractHttpConfigurer.class, getClass().getClassLoader())) |
| 385 | + .thenReturn(List.of(new WithCustomDsl())); |
| 386 | + this.spring.register(WithCustomDslDisabledConfig.class, UserDetailsConfig.class).autowire(); |
| 387 | + SecurityFilterChain filterChain = this.spring.getContext().getBean(SecurityFilterChain.class); |
| 388 | + List<Filter> filters = filterChain.getFilters(); |
| 389 | + assertThat(filters).doesNotHaveAnyElementsOfTypes(UsernamePasswordAuthenticationFilter.class); |
| 390 | + this.mockMvc.perform(formLogin()).andExpectAll(status().isNotFound(), unauthenticated()); |
| 391 | + } |
| 392 | + |
368 | 393 | @RestController
|
369 | 394 | static class NameController {
|
370 | 395 |
|
@@ -661,4 +686,45 @@ public void configure(HttpSecurity builder) {
|
661 | 686 |
|
662 | 687 | }
|
663 | 688 |
|
| 689 | + @Configuration |
| 690 | + @EnableWebSecurity |
| 691 | + static class WithCustomDslConfig { |
| 692 | + |
| 693 | + @Bean |
| 694 | + SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |
| 695 | + // @formatter:off |
| 696 | + http |
| 697 | + .with(new WithCustomDsl(), Customizer.withDefaults()) |
| 698 | + .httpBasic(Customizer.withDefaults()); |
| 699 | + // @formatter:on |
| 700 | + return http.build(); |
| 701 | + } |
| 702 | + |
| 703 | + } |
| 704 | + |
| 705 | + @Configuration |
| 706 | + @EnableWebSecurity |
| 707 | + static class WithCustomDslDisabledConfig { |
| 708 | + |
| 709 | + @Bean |
| 710 | + SecurityFilterChain filterChain(HttpSecurity http) throws Exception { |
| 711 | + // @formatter:off |
| 712 | + http |
| 713 | + .with(new WithCustomDsl(), (dsl) -> dsl.disable()) |
| 714 | + .httpBasic(Customizer.withDefaults()); |
| 715 | + // @formatter:on |
| 716 | + return http.build(); |
| 717 | + } |
| 718 | + |
| 719 | + } |
| 720 | + |
| 721 | + static class WithCustomDsl extends AbstractHttpConfigurer<WithCustomDsl, HttpSecurity> { |
| 722 | + |
| 723 | + @Override |
| 724 | + public void init(HttpSecurity builder) throws Exception { |
| 725 | + builder.formLogin(Customizer.withDefaults()); |
| 726 | + } |
| 727 | + |
| 728 | + } |
| 729 | + |
664 | 730 | }
|
0 commit comments