我正在使用 Spring Security Oauth2 来保护我的 Spring Boot REST 应用程序。我想在用户登录成功和失败后处理一些操作。问题是每个
当我使用用户承载 token 发送请求时,即使用户已经通过身份验证,AuthenticationSuccessEvent
也会发布。
这个处理程序总是被调用:
@Async
@EventListener( { AuthenticationSuccessEvent.class } )
public void listenAuthenticationSuccessEvent( AuthenticationSuccessEvent event ) {
AbstractAuthenticationToken auth = (AbstractAuthenticationToken) event
.getSource();
log.info( "User connected: {}", auth.getName() );
}
正常吗?我希望它被调用一次。
感谢您的帮助
最佳答案
默认情况下(从 Spring 5.x 开始)在每个 token /refresh_token 上调用 AuthenticationSuccessEvent 事件的原因是因为“Authorization: Basic clientID:clientSecret” header 作为 token 请求的一部分呈现,因此请求由 BasicAuthenticationFilter 处理,并使用相应的 AuthenticationManager(ProviderManager)(除了 ProviderManager 之外)对客户端进行身份验证em> 负责 token auth) 的实现。
每个ProviderManager依次具有AuthenticationEventPublisher依赖项,用于发布不同类型的事件,在我们的例子中(auth success),它是eventPublisher .publishAuthenticationSuccess(结果);
默认情况下,ProviderManager 使用 NullEventPublisher,可以使用 ProviderManager#setAuthenticationEventPublisher setter 覆盖。
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) {
}
}
}
关于spring-boot - Spring Security Oauth2 AuthenticationSuccessEvent 在每个请求时发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50663431/