Ability to configure authenticationDetailsSource in AnonymousConfigurer
Closes gh-17831 Signed-off-by: DingHao <dh.hiekn@gmail.com>
This commit is contained in:
		
							parent
							
								
									10935632ee
								
							
						
					
					
						commit
						57d9678b4b
					
				|  | @ -19,7 +19,10 @@ package org.springframework.security.config.annotation.web.configurers; | |||
| import java.util.List; | ||||
| import java.util.UUID; | ||||
| 
 | ||||
| import jakarta.servlet.http.HttpServletRequest; | ||||
| 
 | ||||
| import org.springframework.security.authentication.AnonymousAuthenticationProvider; | ||||
| import org.springframework.security.authentication.AuthenticationDetailsSource; | ||||
| import org.springframework.security.authentication.AuthenticationProvider; | ||||
| import org.springframework.security.config.Customizer; | ||||
| import org.springframework.security.config.annotation.SecurityConfigurer; | ||||
|  | @ -39,6 +42,7 @@ import org.springframework.security.web.authentication.AnonymousAuthenticationFi | |||
|  * other than applying this {@link SecurityConfigurer}. | ||||
|  * | ||||
|  * @author Rob Winch | ||||
|  * @author DingHao | ||||
|  * @since 3.2 | ||||
|  */ | ||||
| public final class AnonymousConfigurer<H extends HttpSecurityBuilder<H>> | ||||
|  | @ -50,6 +54,8 @@ public final class AnonymousConfigurer<H extends HttpSecurityBuilder<H>> | |||
| 
 | ||||
| 	private AnonymousAuthenticationFilter authenticationFilter; | ||||
| 
 | ||||
| 	private AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource; | ||||
| 
 | ||||
| 	private Object principal = "anonymousUser"; | ||||
| 
 | ||||
| 	private List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_ANONYMOUS"); | ||||
|  | @ -142,6 +148,19 @@ public final class AnonymousConfigurer<H extends HttpSecurityBuilder<H>> | |||
| 		return this; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Specifies a custom {@link AuthenticationDetailsSource} to use for anonymous | ||||
| 	 * authentication. | ||||
| 	 * @param authenticationDetailsSource the custom {@link AuthenticationDetailsSource} | ||||
| 	 * to use | ||||
| 	 * @return {@link AnonymousConfigurer} for additional customization | ||||
| 	 */ | ||||
| 	public AnonymousConfigurer<H> authenticationDetailsSource( | ||||
| 			AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource) { | ||||
| 		this.authenticationDetailsSource = authenticationDetailsSource; | ||||
| 		return this; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public void init(H http) { | ||||
| 		if (this.authenticationProvider == null) { | ||||
|  | @ -156,6 +175,9 @@ public final class AnonymousConfigurer<H extends HttpSecurityBuilder<H>> | |||
| 		if (this.authenticationFilter == null) { | ||||
| 			this.authenticationFilter = new AnonymousAuthenticationFilter(getKey(), this.principal, this.authorities); | ||||
| 		} | ||||
| 		if (this.authenticationDetailsSource != null) { | ||||
| 			this.authenticationFilter.setAuthenticationDetailsSource(this.authenticationDetailsSource); | ||||
| 		} | ||||
| 		this.authenticationFilter.setSecurityContextHolderStrategy(getSecurityContextHolderStrategy()); | ||||
| 		this.authenticationFilter.afterPropertiesSet(); | ||||
| 		http.addFilter(this.authenticationFilter); | ||||
|  |  | |||
|  | @ -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,7 @@ import org.springframework.beans.factory.annotation.Autowired; | |||
| 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.annotation.SecurityContextChangedListenerConfig; | ||||
| import org.springframework.security.config.annotation.web.builders.HttpSecurity; | ||||
| import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | ||||
|  | @ -39,6 +41,8 @@ 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 +105,37 @@ public class AnonymousConfigurerTests { | |||
| 		this.mockMvc.perform(get("/")).andExpect(status().isOk()).andExpect(content().string("myAnonymousUser")); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void anonymousAuthenticationWhenUsingAuthenticationDetailsSourceRefThenMatchesNamespace() throws Exception { | ||||
| 		this.spring.register(AuthenticationDetailsSourceAnonymousConfig.class).autowire(); | ||||
| 		AuthenticationDetailsSource<HttpServletRequest, ?> source = this.spring.getContext() | ||||
| 			.getBean(AuthenticationDetailsSource.class); | ||||
| 		this.mockMvc.perform(get("/")); | ||||
| 		verify(source).buildDetails(any(HttpServletRequest.class)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Configuration | ||||
| 	@EnableWebSecurity | ||||
| 	@EnableWebMvc | ||||
| 	static class AuthenticationDetailsSourceAnonymousConfig { | ||||
| 
 | ||||
| 		AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = mock( | ||||
| 				AuthenticationDetailsSource.class); | ||||
| 
 | ||||
| 		@Bean | ||||
| 		SecurityFilterChain filterChain(HttpSecurity http) throws Exception { | ||||
| 			return http | ||||
| 				.anonymous((anonymous) -> anonymous.authenticationDetailsSource(this.authenticationDetailsSource)) | ||||
| 				.build(); | ||||
| 		} | ||||
| 
 | ||||
| 		@Bean | ||||
| 		AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource() { | ||||
| 			return this.authenticationDetailsSource; | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	@Configuration | ||||
| 	@EnableWebSecurity | ||||
| 	@EnableWebMvc | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue