使用Spring Security 3登录处理程序处理失败的登录通知

时间:2013-08-20 17:59:45

标签: spring authentication spring-security

在我的应用程序中,我想为我的用户增加一个失败的登录尝试计数器,并在使用Spring Security 3.1.4.RELEASE达到某个尝试次数时将其锁定。

我成功实现了一个简单的登录成功通知处理程序,它将计数器重置为零并将此状态保存在我的数据库中,如此。

public class BitfoodLoginSuccessHandler extends BitfoodAuthHandler implements AuthenticationSuccessHandler {

  @Override
  public void onAuthenticationSuccess(HttpServletRequest arg0,
      HttpServletResponse arg1, Authentication arg2) throws IOException,
      ServletException {

    String userName = arg2.getName();
    AppUser result = getBitfoodDao().getAuthDao().getUser(userName);

    if (result.getLoginStatus().getStatus() == UserLoginStatus.STATUS_ACTIVE) {
      result.getLoginStatus().setLoginFailCount(0);
      getBitfoodDao().getAuthDao().save(result);
    } // TODO redirect on success.
  }
}

但是,我试图弄清楚如何在失败事件处理程序中实现相反的情况,具体来说,是org.springframework.security.web.authentication.AuthenticationFailureHandler的实现。

public class BitfoodLoginFailedHandler extends BitfoodAuthHandler implements
    AuthenticationFailureHandler {

  @Override
  public void onAuthenticationFailure(HttpServletRequest arg0,
      HttpServletResponse arg1, AuthenticationException arg2)
      throws IOException, ServletException {
    log.info("???????");
    /*if (ls.getLoginFailCount() >= 3) { // TODO parameterize this value
      ls.setStatus(UserLoginStatus.STATUS_LOCKED);
    }*/
  }
}

我知道org.springframework.security.core.AuthenticationException取消了这两种可能提供我需要的登录信息的方法。具体来说,我试图找出哪个用户名(如果有的话,如果它确实是我在DB上的用户)已经失败了当前的登录尝试。

org.springframework.security.core.AuthenticationException

AuthenticationException::getAuthentication()
AuthenticationException::getExtraInformation() 

但是,两个方法都在API 3.1.x版中标记为已弃用。所以:

1)我是否有另一种方法可以使用这些通知处理程序检索尝试失败的登录用户名?

2)我是否应该考虑使用另一种机制来执行此逻辑?如果是这样,Spring Security 3会提供哪些替代方案?

更新:哇,@ axtavt的回答起作用并且结束了比我想象的更清洁,因为我不再需要弄乱我的安全管理器的过滤器配置了。尼斯!

更新的代码:

我更改了自定义类的接口:

public class BitfoodLoginFailedHandler extends BitfoodAuthHandler 
    implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> 

public class BitfoodLoginSuccessHandler extends BitfoodAuthHandler 
    implements ApplicationListener<AuthenticationSuccessEvent>

我实施了适当的方法:

public void onApplicationEvent(AuthenticationSuccessEvent event)
public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent event)

将它们的bean上下文定义保留为原样:

<beans:bean id="successHandler" class="org.bitfood.admin.auth.BitfoodLoginSuccessHandler">
    <beans:property name="bitfoodDao" ref="daoService"/>
</beans:bean>

<beans:bean id="failureHandler" class="org.bitfood.admin.auth.BitfoodLoginFailedHandler">
    <beans:property name="bitfoodDao" ref="daoService"/>
</beans:bean>

而且瞧!在请求结束前收到适当的通知(包括用户名数据)。

谢谢!

1 个答案:

答案 0 :(得分:4)

接收有关身份验证事件的通知的另一种方法是由Spring Security广播listen for ApplicationEvents,即AuthenticationSuccessEventAbstractAuthenticationFailureEvent