spring-boot - Spring Security Oauth2 AuthenticationSuccessEvent 在每个请求时发布

标签 spring-boot authentication spring-security spring-security-oauth2

我正在使用 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/

相关文章:

spring-security - 解决 Kotlin 中的意外覆盖错误

Spring Boot + Hazelcast MapStore 无法 Autowiring 存储库

spring - Spring Boot与MySQL中的多个架构连接

java - 在不加载 Spring 上下文的情况下测试 @ConfigurationProperties 注释

spring - 配置类中@EnableWebSecurity 的原因

java - 使用 GWT 获取/j_spring_security_check 的 HTTP 状态 404

spring - 在@WebMvcTest 中指定@SpringBootApplication

asp.net-mvc - ASP.NET MVC 检查用户是否属于 [x] 组

java - 跨客户端身份服务器到客户端传递访问 token

javascript - 在 Vuejs 中使用带有 Axios 的 HTTP 基本身份验证时出现 401 错误