mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	AuthenticationEventPublisher Bean Lookup
Issue gh-7793 Fixes gh-7515
This commit is contained in:
		
							parent
							
								
									fc9b97c94a
								
							
						
					
					
						commit
						5579846263
					
				| @ -26,6 +26,7 @@ import java.util.Set; | |||||||
| 
 | 
 | ||||||
| import org.apache.commons.logging.Log; | import org.apache.commons.logging.Log; | ||||||
| import org.apache.commons.logging.LogFactory; | import org.apache.commons.logging.LogFactory; | ||||||
|  | 
 | ||||||
| import org.springframework.aop.TargetSource; | import org.springframework.aop.TargetSource; | ||||||
| import org.springframework.aop.framework.Advised; | import org.springframework.aop.framework.Advised; | ||||||
| import org.springframework.aop.target.LazyInitTargetSource; | import org.springframework.aop.target.LazyInitTargetSource; | ||||||
| @ -36,6 +37,7 @@ import org.springframework.beans.factory.annotation.Autowired; | |||||||
| import org.springframework.context.ApplicationContext; | import org.springframework.context.ApplicationContext; | ||||||
| import org.springframework.core.annotation.Order; | import org.springframework.core.annotation.Order; | ||||||
| import org.springframework.core.io.support.SpringFactoriesLoader; | import org.springframework.core.io.support.SpringFactoriesLoader; | ||||||
|  | import org.springframework.security.authentication.AuthenticationEventPublisher; | ||||||
| import org.springframework.security.authentication.AuthenticationManager; | import org.springframework.security.authentication.AuthenticationManager; | ||||||
| import org.springframework.security.authentication.AuthenticationTrustResolver; | import org.springframework.security.authentication.AuthenticationTrustResolver; | ||||||
| import org.springframework.security.authentication.AuthenticationTrustResolverImpl; | import org.springframework.security.authentication.AuthenticationTrustResolverImpl; | ||||||
| @ -194,8 +196,7 @@ public abstract class WebSecurityConfigurerAdapter implements | |||||||
| 			return http; | 			return http; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		DefaultAuthenticationEventPublisher eventPublisher = objectPostProcessor | 		AuthenticationEventPublisher eventPublisher = getAuthenticationEventPublisher(); | ||||||
| 				.postProcess(new DefaultAuthenticationEventPublisher()); |  | ||||||
| 		localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher); | 		localConfigureAuthenticationBldr.authenticationEventPublisher(eventPublisher); | ||||||
| 
 | 
 | ||||||
| 		AuthenticationManager authenticationManager = authenticationManager(); | 		AuthenticationManager authenticationManager = authenticationManager(); | ||||||
| @ -407,6 +408,13 @@ public abstract class WebSecurityConfigurerAdapter implements | |||||||
| 		this.authenticationConfiguration = authenticationConfiguration; | 		this.authenticationConfiguration = authenticationConfiguration; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	private AuthenticationEventPublisher getAuthenticationEventPublisher() { | ||||||
|  | 		if (this.context.getBeanNamesForType(AuthenticationEventPublisher.class).length > 0) { | ||||||
|  | 			return this.context.getBean(AuthenticationEventPublisher.class); | ||||||
|  | 		} | ||||||
|  | 		return this.objectPostProcessor.postProcess(new DefaultAuthenticationEventPublisher()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Creates the shared objects | 	 * Creates the shared objects | ||||||
| 	 * | 	 * | ||||||
|  | |||||||
| @ -33,6 +33,7 @@ import org.springframework.context.annotation.Bean; | |||||||
| import org.springframework.context.annotation.Configuration; | import org.springframework.context.annotation.Configuration; | ||||||
| import org.springframework.core.annotation.AnnotationAwareOrderComparator; | import org.springframework.core.annotation.AnnotationAwareOrderComparator; | ||||||
| import org.springframework.core.annotation.Order; | import org.springframework.core.annotation.Order; | ||||||
|  | import org.springframework.security.authentication.AuthenticationEventPublisher; | ||||||
| import org.springframework.security.authentication.AuthenticationTrustResolver; | import org.springframework.security.authentication.AuthenticationTrustResolver; | ||||||
| import org.springframework.security.authentication.event.AuthenticationSuccessEvent; | import org.springframework.security.authentication.event.AuthenticationSuccessEvent; | ||||||
| import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; | ||||||
| @ -40,9 +41,11 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; | |||||||
| import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; | ||||||
| import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; | ||||||
| import org.springframework.security.config.test.SpringTestRule; | import org.springframework.security.config.test.SpringTestRule; | ||||||
|  | import org.springframework.security.core.Authentication; | ||||||
| import org.springframework.security.core.userdetails.PasswordEncodedUser; | import org.springframework.security.core.userdetails.PasswordEncodedUser; | ||||||
| import org.springframework.security.core.userdetails.UserDetailsService; | import org.springframework.security.core.userdetails.UserDetailsService; | ||||||
| import org.springframework.security.core.userdetails.UsernameNotFoundException; | import org.springframework.security.core.userdetails.UsernameNotFoundException; | ||||||
|  | import org.springframework.security.provisioning.InMemoryUserDetailsManager; | ||||||
| import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; | ||||||
| import org.springframework.test.web.servlet.MockMvc; | import org.springframework.test.web.servlet.MockMvc; | ||||||
| import org.springframework.web.accept.ContentNegotiationStrategy; | import org.springframework.web.accept.ContentNegotiationStrategy; | ||||||
| @ -51,8 +54,11 @@ import org.springframework.web.filter.OncePerRequestFilter; | |||||||
| 
 | 
 | ||||||
| import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
| import static org.assertj.core.api.ThrowableAssert.catchThrowable; | import static org.assertj.core.api.ThrowableAssert.catchThrowable; | ||||||
|  | import static org.mockito.ArgumentMatchers.any; | ||||||
| import static org.mockito.Mockito.mock; | import static org.mockito.Mockito.mock; | ||||||
|  | import static org.mockito.Mockito.verify; | ||||||
| import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin; | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin; | ||||||
|  | import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; | ||||||
| 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.result.MockMvcResultMatchers.header; | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; | ||||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||||||
| @ -364,4 +370,32 @@ public class WebSecurityConfigurerAdapterTests { | |||||||
| 	@Order | 	@Order | ||||||
| 	static class LowestPriorityWebSecurityConfig extends WebSecurityConfigurerAdapter { | 	static class LowestPriorityWebSecurityConfig extends WebSecurityConfigurerAdapter { | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	// gh-7515 | ||||||
|  | 	@Test | ||||||
|  | 	public void performWhenUsingAuthenticationEventPublisherBeanThenUses() throws Exception { | ||||||
|  | 		this.spring.register(CustomAuthenticationEventPublisherBean.class).autowire(); | ||||||
|  | 
 | ||||||
|  | 		AuthenticationEventPublisher authenticationEventPublisher = | ||||||
|  | 				this.spring.getContext().getBean(AuthenticationEventPublisher.class); | ||||||
|  | 
 | ||||||
|  | 		this.mockMvc.perform(get("/") | ||||||
|  | 				.with(httpBasic("user", "password"))); | ||||||
|  | 
 | ||||||
|  | 		verify(authenticationEventPublisher).publishAuthenticationSuccess(any(Authentication.class)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@EnableWebSecurity | ||||||
|  | 	static class CustomAuthenticationEventPublisherBean extends WebSecurityConfigurerAdapter { | ||||||
|  | 		@Bean | ||||||
|  | 		@Override | ||||||
|  | 		public UserDetailsService userDetailsService() { | ||||||
|  | 			return new InMemoryUserDetailsManager(PasswordEncodedUser.user()); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		@Bean | ||||||
|  | 		public AuthenticationEventPublisher authenticationEventPublisher() { | ||||||
|  | 			return mock(AuthenticationEventPublisher.class); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -73,6 +73,7 @@ import org.springframework.http.ResponseEntity; | |||||||
| import org.springframework.mock.web.MockHttpServletRequest; | import org.springframework.mock.web.MockHttpServletRequest; | ||||||
| import org.springframework.security.access.prepost.PreAuthorize; | import org.springframework.security.access.prepost.PreAuthorize; | ||||||
| import org.springframework.security.authentication.AbstractAuthenticationToken; | import org.springframework.security.authentication.AbstractAuthenticationToken; | ||||||
|  | import org.springframework.security.authentication.AuthenticationEventPublisher; | ||||||
| import org.springframework.security.authentication.AuthenticationManager; | import org.springframework.security.authentication.AuthenticationManager; | ||||||
| import org.springframework.security.authentication.AuthenticationManagerResolver; | import org.springframework.security.authentication.AuthenticationManagerResolver; | ||||||
| import org.springframework.security.authentication.AuthenticationProvider; | import org.springframework.security.authentication.AuthenticationProvider; | ||||||
| @ -88,6 +89,7 @@ import org.springframework.security.core.GrantedAuthority; | |||||||
| import org.springframework.security.core.authority.SimpleGrantedAuthority; | import org.springframework.security.core.authority.SimpleGrantedAuthority; | ||||||
| import org.springframework.security.core.userdetails.UserDetailsService; | import org.springframework.security.core.userdetails.UserDetailsService; | ||||||
| import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrincipal; | import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrincipal; | ||||||
|  | import org.springframework.security.oauth2.core.OAuth2AuthenticationException; | ||||||
| import org.springframework.security.oauth2.core.OAuth2Error; | import org.springframework.security.oauth2.core.OAuth2Error; | ||||||
| import org.springframework.security.oauth2.core.OAuth2TokenValidator; | import org.springframework.security.oauth2.core.OAuth2TokenValidator; | ||||||
| import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult; | import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult; | ||||||
| @ -99,8 +101,8 @@ import org.springframework.security.oauth2.jwt.JwtTimestampValidator; | |||||||
| import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; | import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; | ||||||
| import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; | import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; | ||||||
| import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; | import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; | ||||||
| import org.springframework.security.oauth2.server.resource.authentication.JwtIssuerAuthenticationManagerResolver; |  | ||||||
| import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; | import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; | ||||||
|  | import org.springframework.security.oauth2.server.resource.authentication.JwtIssuerAuthenticationManagerResolver; | ||||||
| import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector; | import org.springframework.security.oauth2.server.resource.introspection.NimbusOpaqueTokenIntrospector; | ||||||
| import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector; | import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector; | ||||||
| import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint; | import org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationEntryPoint; | ||||||
| @ -1091,6 +1093,22 @@ public class OAuth2ResourceServerConfigurerTests { | |||||||
| 				.andExpect(invalidTokenHeader("algorithm")); | 				.andExpect(invalidTokenHeader("algorithm")); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// gh-7793 | ||||||
|  | 	@Test | ||||||
|  | 	public void requestWhenUsingCustomAuthenticationEventPublisherThenUses() throws Exception{ | ||||||
|  | 		this.spring.register(CustomAuthenticationEventPublisher.class).autowire(); | ||||||
|  | 
 | ||||||
|  | 		when(bean(JwtDecoder.class).decode(anyString())) | ||||||
|  | 				.thenThrow(new JwtException("problem")); | ||||||
|  | 
 | ||||||
|  | 		this.mvc.perform(get("/").with(bearerToken("token"))); | ||||||
|  | 
 | ||||||
|  | 		verifyBean(AuthenticationEventPublisher.class) | ||||||
|  | 				.publishAuthenticationFailure( | ||||||
|  | 						any(OAuth2AuthenticationException.class), | ||||||
|  | 						any(Authentication.class)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	@Test | 	@Test | ||||||
| 	public void getWhenCustomJwtAuthenticationManagerThenUsed() throws Exception { | 	public void getWhenCustomJwtAuthenticationManagerThenUsed() throws Exception { | ||||||
| 		this.spring.register(JwtAuthenticationManagerConfig.class, BasicController.class).autowire(); | 		this.spring.register(JwtAuthenticationManagerConfig.class, BasicController.class).autowire(); | ||||||
| @ -2015,6 +2033,31 @@ public class OAuth2ResourceServerConfigurerTests { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@EnableWebSecurity | ||||||
|  | 	static class CustomAuthenticationEventPublisher extends WebSecurityConfigurerAdapter { | ||||||
|  | 		@Override | ||||||
|  | 		protected void configure(HttpSecurity http) throws Exception { | ||||||
|  | 			// @formatter:off | ||||||
|  | 			http | ||||||
|  | 				.authorizeRequests() | ||||||
|  | 					.anyRequest().authenticated() | ||||||
|  | 					.and() | ||||||
|  | 				.oauth2ResourceServer() | ||||||
|  | 					.jwt(); | ||||||
|  | 			// @formatter:on | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		@Bean | ||||||
|  | 		JwtDecoder jwtDecoder() { | ||||||
|  | 			return mock(JwtDecoder.class); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		@Bean | ||||||
|  | 		AuthenticationEventPublisher authenticationEventPublisher() { | ||||||
|  | 			return mock(AuthenticationEventPublisher.class); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	@EnableWebSecurity | 	@EnableWebSecurity | ||||||
| 	static class OpaqueTokenConfig extends WebSecurityConfigurerAdapter { | 	static class OpaqueTokenConfig extends WebSecurityConfigurerAdapter { | ||||||
| 		@Override | 		@Override | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user