默认情况下(从 Spring 5.x 开始)在每个令牌/refresh_token 上调用 AuthenticationSuccessEvent 事件的原因是因为 "Authorization: Basic clientID:clientSecret"标头作为令牌请求的一部分呈现,因此请求由 BasicAuthenticationFilter 处理,并使用相应的 AuthenticationManager(ProviderManager) 对客户端进行身份验证(除了 ProviderManager em> 负责令牌认证)的实施。
每个 ProviderManager 依次具有 AuthenticationEventPublisher 依赖项,用于发布不同类型的事件,在我们的例子中(认证成功),它是 eventPublisher .publishAuthenticationSuccess(result);
默认情况下 ProviderManager 使用 NullEventPublisher 可以使用 ProviderManager#setAuthenticationEventPublisher 设置器覆盖。
ProviderManager 由 'AuthenticationManagerBuilder 创建,并为其设置相应的事件发布者(如果不为空)。
protected ProviderManager performBuild() throws Exception {
...
ProviderManager providerManager = new ProviderManager(authenticationProviders,
parentAuthenticationManager);
...
if (eventPublisher != null) {
providerManager.setAuthenticationEventPublisher(eventPublisher);
}
AuthenticationManagerBuilder 由 WebSecurityConfigurerAdapter 填充,请参阅 WebSecurityConfigurerAdapter#getHttp 方法,您可以在其中找到以下行(在 Spring Security 5.x 中添加):
authenticationBuilder.authenticationEventPublisher(eventPublisher);
覆盖该默认行为的方法之一是实现相应的 BasicWebSecurityConfig(扩展 WebSecurityConfigurerAdapter 或 AuthorizationServerSecurityConfiguration)并在创建 ProviderManager 之前将 NullEventPublisher 设置为 'AuthenticationManagerBuilder: p>
@Configuration
@Order(-1)
public class BasicSecurityConfiguration extends AuthorizationServerSecurityConfiguration {
@Override
protected void configure(HttpSecurity http) throws Exception {
super.configure(http);
// override default DefaultAuthenticationEventPublisher to avoid excessive firing of
// AuthenticationSuccessEvent on successful client credentials verification that passed in "Authorization: Basic clientId:clientSecret" header
http.getSharedObject(AuthenticationManagerBuilder.class).authenticationEventPublisher(new NullEventPublisher());
http.httpBasic()
}
private static final class NullEventPublisher implements AuthenticationEventPublisher {
public void publishAuthenticationFailure(AuthenticationException exception, Authentication authentication) {
}
public void publishAuthenticationSuccess(Authentication authentication) {
}
}
}