Spring AbstractAuthenticationFailureEvent认证失败事件未触发问题咨询
问题排查思路
- 检查监听器类是否被Spring容器托管:包含监听方法的类必须添加
@Component、@Service等容器注解,且处于项目组件扫描的路径范围内,否则Spring无法识别事件监听方法。 - 检查认证异常类型是否符合要求:
DefaultAuthenticationEventPublisher默认只会识别Spring Security标准的AuthenticationException子类异常,只有认证流程抛出该类型的异常时才会触发AbstractAuthenticationFailureEvent事件发布。 - 检查异常抛出位置是否正确:如果在配置类的
configure方法中捕获认证异常再抛出自定义异常,会绕开事件发布器的监听逻辑,导致事件无法发布。 - 检查包导入是否正确:确认监听方法参数的
AbstractAuthenticationFailureEvent是org.springframework.security.authentication.event包下的类,避免导入其他同名类导致监听不匹配。 - 检查
ApplicationEventPublisher注入是否正确:配置类中的applicationEventPublisher必须是Spring自动注入的实例,未正确注入的情况下事件发布器无法正常工作。
解决方案
- 托管监听器类
给包含认证失败监听方法的类添加@Component注解,示例如下:
@Component public class AuthEventListener { @EventListener public void authFailedEventListener(AbstractAuthenticationFailureEvent authenticationFailureEvent) { // 原有业务逻辑 if(authenticationFailureEvent instanceof AbstractAuthenticationFailureEvent) { System.out.print(true); }else { System.out.print(false); } System.out.println(authenticationFailureEvent); System.out.print("Event Catched for Failed"); } }
- 统一异常继承关系
自定义的认证失败异常必须继承org.springframework.security.core.AuthenticationException,而不是直接继承RuntimeException或其他非认证异常类,示例如下:
public class CustomOauthException extends AuthenticationException { public CustomOauthException(String msg) { super(msg); } }
- 调整异常抛出位置
将自定义异常的抛出逻辑从configure方法迁移到自定义AuthenticationProvider的authenticate方法中,认证失败时直接抛出AuthenticationException子类异常,示例如下:
@Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { // 执行账号密码校验等认证逻辑 if(认证失败条件) { throw new CustomOauthException("认证失败具体原因"); } // 认证成功返回认证信息 }
对应调整配置类的configure方法,删除多余的异常捕获逻辑:
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception{ auth.authenticationProvider(customAuthentication); auth.authenticationEventPublisher(new DefaultAuthenticationEventPublisher(applicationEventPublisher)); }
- (可选)添加自定义异常映射
如果存在需要单独映射的自定义认证异常,可以给DefaultAuthenticationEventPublisher添加额外的异常映射关系:
DefaultAuthenticationEventPublisher eventPublisher = new DefaultAuthenticationEventPublisher(applicationEventPublisher); eventPublisher.setAdditionalExceptionMappings(Collections.singletonMap(CustomOauthException.class, AuthenticationFailureBadCredentialsEvent.class)); auth.authenticationEventPublisher(eventPublisher);
内容的提问来源于stack exchange,提问作者vinay saddanapu
相关产品推荐
相关产品推荐

