diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/AnonymousConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/AnonymousConfigurer.java index ab9770a13e..cfaef882e6 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/AnonymousConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/AnonymousConfigurer.java @@ -39,6 +39,7 @@ * other than applying this {@link SecurityConfigurer}. * * @author Rob Winch + * @author DingHao * @since 3.2 */ public final class AnonymousConfigurer> @@ -158,7 +159,7 @@ public void configure(H http) { } this.authenticationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy()); this.authenticationFilter.afterPropertiesSet(); - http.addFilter(this.authenticationFilter); + http.addFilter(postProcess(this.authenticationFilter)); } private String getKey() { diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/AnonymousConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/AnonymousConfigurerTests.java index f53683c163..b8963fcbd3 100644 --- a/config/src/test/java/org/springframework/security/config/annotation/web/configurers/AnonymousConfigurerTests.java +++ b/config/src/test/java/org/springframework/security/config/annotation/web/configurers/AnonymousConfigurerTests.java @@ -16,6 +16,7 @@ package org.springframework.security.config.annotation.web.configurers; +import jakarta.servlet.http.HttpServletRequest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -23,6 +24,8 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AnonymousAuthenticationToken; +import org.springframework.security.authentication.AuthenticationDetailsSource; +import org.springframework.security.config.ObjectPostProcessor; import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; @@ -34,11 +37,14 @@ import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.provisioning.InMemoryUserDetailsManager; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.AnonymousAuthenticationFilter; import org.springframework.test.web.servlet.MockMvc; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.springframework.security.config.Customizer.withDefaults; import static org.springframework.security.config.annotation.SecurityContextChangedListenerArgumentMatchers.setAuthentication; @@ -101,6 +107,45 @@ public void shouldReturnMyCustomAnonymousConfig() throws Exception { this.mockMvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("myAnonymousUser")); } + @Test + public void anonymousAuthenticationWhenUsingAuthenticationDetailsSourceRefThenMatchesNamespace() throws Exception { + this.spring.register(AuthenticationDetailsSourceAnonymousConfig.class).autowire(); + AuthenticationDetailsSource source = this.spring.getContext() + .getBean(AuthenticationDetailsSource.class); + this.mockMvc.perform(get("/")); + verify(source).buildDetails(any(HttpServletRequest.class)); + } + + @Configuration + @EnableWebSecurity + @EnableWebMvc + static class AuthenticationDetailsSourceAnonymousConfig { + + AuthenticationDetailsSource authenticationDetailsSource = mock( + AuthenticationDetailsSource.class); + + @Bean + SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + return http.anonymous((anonymous) -> anonymous + .withObjectPostProcessor(new ObjectPostProcessor() { + + @Override + public O postProcess(O object) { + object.setAuthenticationDetailsSource( + AuthenticationDetailsSourceAnonymousConfig.this.authenticationDetailsSource); + return object; + } + + })).build(); + } + + @Bean + AuthenticationDetailsSource authenticationDetailsSource() { + return this.authenticationDetailsSource; + } + + } + @Configuration @EnableWebSecurity @EnableWebMvc