When building a SecurityFilterChain from HttpSecurity, a prototype is built in HttpSecurityConfiguration. However, this prototype is not aware of AuthenticationEventPublisher in the bean factory. Although it is possible to set AuthenticationEventPublisher later, I think it is inconvenient and is not an expected behaviour. I would like to know if this pattern is by design or is a place for an improvement.

Comment From: zhenchuan9r

The HttpSecurity prototype is by default installed with a null AuthenticationEventPublisher.

Comment From: eleftherias

Thanks for starting this discussion @zhenchuan9r.

You mentioned this in the original post, but for anyone else arriving at this issue, I will point out that you can configure an AuthenticationEventPublisher bean yourself:

@Bean
public AuthenticationEventPublisher authenticationEventPublisher
        (ApplicationEventPublisher applicationEventPublisher) {
    return new DefaultAuthenticationEventPublisher(applicationEventPublisher);
}

When using the WebSecurityConfigurerAdapter, it will create an AuthenticationEventPublisher bean for you. This seems to me like a side-effect and I'm not sure if we would want to make this the default behaviour in HttpSecurityConfiguration. I will have a discussion with the rest of the team and update this issue with additional details.

Comment From: sjohnr

For additional context on this issue, see this comment by @Kehrlann and this sample repo that demonstrates the issue.

I think we could make the upgrade path to using an @Bean instead of WebSecurityConfigurerAdapter easier if we add consistency here.

After a bit of discussion, here are some notes:

  • HttpSecurityConfiguration.httpSecurity() is (more or less) the equivalent to WebSecurityConfigurerAdapter.getHttp()
  • WebSecurityConfigurerAdapter wires an AuthenticationEventPublisher into the local AuthenticationManagerBuilder while HttpSecurityConfiguration does not
  • WebSecurityConfigurerAdapter will create the AuthenticationEventPublisher if it does not exist as a bean
  • The local AuthenticationManagerBuilder is used to build the AuthenticationManager for all non-Dao instances of AuthenticationProvider
  • In both cases, AuthenticationConfiguration creates a global AuthenticationManagerBuilder, adds DaoAuthenticationProvider, and wires an AuthenticationEventPublisher bean if it exists
  • An AuthenticationEventPublisher bean only exists by default through Spring Boot autoconfiguration
  • AuthenticationConfiguration does not create a new instance of AuthenticationEventPublisher if it doesn't already exist

Comment From: sjohnr

Fixed via 0aac515737e385feca81286a6f0bfd1ef2bb90ab (duplicate of gh-11449).