AuthenticationSuccessEvent seems to be fired multiple times for single requests. Not sure if this is expected behavior or not, I will try to create a stripped down app to demonstrate. I just wanted to make sure that this wouldn't be intended behavior. Code configuration is below in Kotlin:
@EnableWebSecurity
class WebSecurityConfiguration: WebSecurityConfigurerAdapter() {
/**
* Spring Authentication Manager
*/
@Bean
override fun authenticationManager(): AuthenticationManager {
return super.authenticationManager()
}
}
@Configuration
@EnableResourceServer
@EnableWebSecurity
@Order(-1)
class ResourceServerConfig(private val authenticationProvider: MongoDBAuthenticationProvider) : ResourceServerConfigurerAdapter() {
// Constants
private val antPatternsForAllUsers = arrayOf("/actuator/**")
@Autowired
fun configureGlobal(auth: AuthenticationManagerBuilder) {
auth.authenticationProvider(authenticationProvider)
}
override fun configure(http: HttpSecurity) {
http
.addFilterBefore(CorsFilter(), SessionManagementFilter::class.java)
.authorizeRequests().antMatchers(*antPatternsForAllUsers).permitAll().and()
.authorizeRequests().anyRequest().authenticated().and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.csrf().disable()
}
}
@Component
class AuthListener {
@EventListener
fun authenticationFailed(event: OAuth2AuthenticationFailureEvent) {
System.out.println("OAuth2AuthenticationFailureEvent")
}
@EventListener
fun authenticationSucceeded(event: AuthenticationSuccessEvent) {
System.out.println("AuthenticationSuccessEvent " + event.toString())
}
@EventListener fun authenticationFailed(event: AuthenticationFailureBadCredentialsEvent) {
System.out.println("AuthenticationFailureBadCredentialsEvent " + event.toString())
}
}
Comment From: jzheaux
Hey, @kibbled! Thanks for the report. It's a little confusing, but would you please report this ticket in https://github.com/spring-projects/spring-security-oauth2-boot? Thank you!
Comment From: tadaskay
I am also observing the same issue with 5.1.x, had to downgrade security-config and security-core to 5.0.9 temporarily. For one BadCredentialsException, there are 2 events published of the same type.
Comment From: jzheaux
@tadaskay is this the issue you are experiencing? https://github.com/spring-projects/spring-security/issues/6281
Comment From: tadaskay
@jzheaux Yes, thank you!
Comment From: jzheaux
Closing this. If the problem persists, please post to https://github.com/spring-projects/spring-security-oauth2-boot/issues
Comment From: zgarcia83
I had the "same issue" but then I realized that the AuthenticationSuccessEvent is called twice as in OAuth2 the client (Application) have to do authentication as well.
I implemented the logic to determine whether the AuthenticationSuccessEvent is called for the client or application user.
Comment From: eranf91
I know that this issue is closed but it seems to be relevant for the latest version of spring security at the moment. I think that the events should be separated.
Comment From: jzheaux
@eranf91 can you clarify what you are wanting to see changed? It might be good for you to open a separate ticket and flesh out a bit more what you mean by:
I think that the events should be separated
Comment From: amirensit
Sorry for commenting on closed issue But I have a solution that worked for me. ( Using the debugging mode ):
-
For the
Client authentication: authenticationSuccessEvent.getSource() is an instance ofOAuth2Authentication. -
For the
User authentication: authenticationSuccessEvent.getSource() is an instance ofUsernamePasswordAuthenticationToken.
So to execute logic only after user authentication :
@Component
public class AuthenticationSuccessEventListener implements ApplicationListener<AuthenticationSuccessEvent> {
@Override
public void onApplicationEvent(AuthenticationSuccessEvent authenticationSuccessEvent) {
if (authenticationSuccessEvent.getSource() instanceof UsernamePasswordAuthenticationToken) {
// the logic here
}
}
}
I hope It helps.
Comment From: isscy
@amirensit Client authentication also source instance of UsernamePasswordAuthenticationToken ! In the ClientCredentialsTokenEndpointFilter.attemptAuthentication or BasicAuthenticationFilter.doFilterInternal , convert clientid, clientSecret from request to UsernamePasswordAuthenticationToken