2013-02-13 116 views
0

我正在使用spring.security.version = 3.1.0.RELEASE。我遇到的问题是由于某种原因AuthenticationFailureCredentialsExpiredEvent未被解雇。Spring Security:AuthenticationFailureCredentialsExpiredEvent未被触发

在调试代码时,我发现AbstractUserDetailsAuthenticationProvider在控制台中显示“用户帐户凭据已过期”。但我仍然困惑于为什么这个事件不被触发。

这里是我的代码:

class JpaUserDetails implements UserDetails { 
... 
... 
    @Override 
    public boolean isCredentialsNonExpired() { 
     if (some logic) { 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 
} 

我确实看到AbstractUserDetailsAuthenticationProvider在控制台中的“用户帐户的凭据已过期”显示,从弹簧下面几行代码:

public abstract class AbstractUserDetailsAuthenticationProvider implements AuthenticationProvider, InitilizeBean, MessageSourceAware { 
... 
... 
    private class DefaultPostAuthenticationChecks implements UserDetailsChecker { 
     public void check(UserDetails user) { 
      if(!user.isCredentialsNonExpired()) { 
       logger.debug("User account credentials have expired"); 
       throw new CredentialsExpiredException(message.getMessage(
          "AbstractUserDetailsAuthenticationProvider.credentialsExpired", 
          "User credentials have expired"), user); 
      } 
     } 
    } 
} 

的问题是,当用户证书过期时,我期待Spring生成AuthenticationFailureCredentialsExpiredEvent事件,我正在通过以下方式处理事件:

class SecurityEventDispatcher implements ApplicationListener<ApplicationEvent> { 
    final List<SecurityEventListener> listeners = new ArrayList<SecurityEventListener>(); 

    public void registerListener(SecurityEventListener listener) { 
     this.listener.add(listener); 
    } 

    public void onApplicationEvent(ApplicationEvent event) { 
     for (SecurityEventListener listener : this.listeners) { 
      if(listener.canHandle(event)) { 
       listener.handle(event); 
      } 
     } 
    } 
} 

这是怎么了处理登录失败事件:

public class LoginFailedEvent extends SecurityEventListener { 

    @Override 
    public boolean canHandle(Object event) { 
     if(event instanceof AbstractAuthenticationFailureEvent) { 
      return true; 
     } 
     else { 
      return false; 
     } 
    } 

    @Override 
    public void handle(Object event) { 
     if (event instanceof AuthenticationFailureBadCredentialsEvent) { 
      // do something 
     } 

     if (event instanceof AuthenticationFailureCredentialsExpiredEvent) { 
      // do something 
     } 
    } 
} 

正如我前面提到的问题是AuthenticationFailureCredentialsExpiredEvent永远不会被解雇。我已经测试了可以正常工作的AuthenticationFailureBadCredentialsEvent。

这是我得到的事件不正确的凭据:(这是工作的罚款)

org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent

这是我在得到事件为过期的密码:

ServletRequestHandledEvent:URL = [/应用/ loginFailure]与failureCause = NULL

有没有人有任何想法可能是错的?任何帮助将不胜感激。

回答

1

下面是这个问题的答案,因为关于这个问题没有太多的文献。

你可能需要设置的ProviderManager的 (的)eventPublisher比 NullEventPublisher以外的东西。没有简单的方法通过 标签来完成此操作,因此您需要使用标准bean配置创建AuthenticationProvider,并将 注入到ProviderManager的标准Spring Bean中。

罗布绞盘 - 春季安全领导

0

如果有人运行到这个问题,只是春季安全升级到3.1.2或+,这个问题是固定的。

+0

你可以分享'security-context.xml'文件 – 2015-09-09 22:13:22