原因是认证成功事件默认情况下(从 Spring 5.x 开始)在每个 token/refresh_token 上调用事件是因为“授权:基本clientID:clientSecret”标头作为令牌请求的一部分呈现,因此请求由基本认证过滤器以及使用相应的身份验证客户端身份验证管理器(提供者管理器)(除了提供者管理器负责令牌验证)的实现。
Each 提供者管理器,反过来,有认证事件发布者用于发布不同类型事件的依赖项,在我们的例子中(auth success),它是eventPublisher.publishAuthenticationSuccess(结果);
默认情况下提供者管理器 uses 空事件发布者可以使用覆盖ProviderManager#setAuthenticationEventPublisher setter.
提供者管理器是由创建的'认证管理器生成器为其设置相应的事件发布者(如果不为空)。
protected ProviderManager performBuild() throws Exception {
...
ProviderManager providerManager = new ProviderManager(authenticationProviders,
parentAuthenticationManager);
...
if (eventPublisher != null) {
providerManager.setAuthenticationEventPublisher(eventPublisher);
}
AuthenticationManagerBuilder 填充自Web安全配置适配器 see WebSecurityConfigurerAdapter#getHttp方法中您可以找到以下行(在 Spring Security 5.x 中添加):
authenticationBuilder.authenticationEventPublisher(eventPublisher);
覆盖该默认行为的方法之一是实现相应的 BasicWebSecurityConfig(扩展 WebSecurityConfigurerAdapter 或 AuthorizationServerSecurityConfiguration)并将 NullEventPublisher 设置为'认证管理器生成器 before 提供者管理器创建:
@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) {
}
}
}