【问题标题】:Spring Security Oauth2 AuthenticationSuccessEvent published at each requestSpring Security Oauth2 AuthenticationSuccessEvent 在每次请求时发布
【发布时间】:2018-11-12 18:38:26
【问题描述】:

我正在使用 Spring Security Oauth2 来保护我的 Spring Boot REST 应用程序。我想在用户登录成功和失败后处理一些操作。问题是每个 当我使用用户持有者令牌发送请求时,即使用户已经通过身份验证,AuthenticationSuccessEvent 也会发布。

这个处理程序总是被调用:

@Async
@EventListener( { AuthenticationSuccessEvent.class } )
public void listenAuthenticationSuccessEvent( AuthenticationSuccessEvent event ) {
    AbstractAuthenticationToken auth = (AbstractAuthenticationToken) event
            .getSource();
    log.info( "User connected: {}", auth.getName() );
}

正常吗?我希望它被调用一次。

感谢您的帮助

【问题讨论】:

  • 是的,这是正常的。每次发送Authentication 标头时,您都会再次登录。如果您不想再次登录,请不要发送 Authentication 标头。
  • 如果您不发送 Authentication 标头,您将如何访问受保护的资源?
  • 如果使用会话,您的会话将通过身份验证。
  • 我禁用了会话,因为它是完整的 OAuth2 安全
  • 如果没有会话,您必须再次登录每个请求。如果您不想再次登录,则需要有状态服务器。

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


【解决方案1】:

默认情况下(从 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) {
    }
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-10
    • 2017-06-08
    • 2016-07-19
    • 2020-05-11
    • 2014-11-05
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多