Spring Security:如何实现暴力检测(BFD)?

Kde*_*per 21 java security spring spring-security brute-force

我的Web应用程序安全性由Spring Security 3.02 处理, 但我找不到任何对Brute Force Detection的开箱即用支持.

我想实现一些应用级别的BFD保护.例如,通过在数据库中存储每个用户的失败登录尝试(JPA).然后,受攻击的用户帐户可以通过电子邮件获得锁定期或强制帐户重新激活.

使用Spring Security实现此功能的最佳方法是什么?是否有任何机构有关于此的示例代码或最佳实践?

Kde*_*per 16

推出自己的BFD并不难.与Spring Security 3.0一样,您只需添加应用程序监听器(感谢Stephen C指出我正确的方向).

当出现身份验证失败时,将调用此侦听器:

@Component
public class AuthenticationFailureListener
    implements ApplicationListener<AuthenticationFailureBadCredentialsEvent> {

  @Autowired
  private UserDao userDao;

  public void onApplicationEvent(AuthenticationFailureBadCredentialsEvent ev) {

    String username = ev.getAuthentication().getName();

    User user = userDao.find("name", username);
    if (user != null) { // only for existing users
            user.reportLoginFailure();
            userDao.commit();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,每个身份验证失败都会通知用户 例如,用户递增认证失败计数器并在达到特定阈值时将其自身停用.

当用户被正确认证时,下面的监听器将通知用户(例如,谁可以重置其认证失败计数器):

@Component
public class AuthenticationSuccessEventListener
    implements ApplicationListener<AuthenticationSuccessEvent>{

  @Autowired
  private UserDao userDao;

  public void onApplicationEvent(AuthenticationSuccessEvent event) {

    String username = event.getAuthentication().getName();

    User user = userDao.find("name", username);
    user.reportLoginOK();
    userDao.commit();
  }
}
Run Code Online (Sandbox Code Playgroud)

上面的监听器不需要额外的XML配置,并且由Spring自动选取(如果它们在Spring组件扫描包中).

根据您的事务配置,如果这些解决方案同时发生,则可能会错过一些失败的登录计数.如果使用单个UPDATE查询更新计数器而不是加载用户然后保存更改,则可以防止这种情况.

上面的侦听器也可以扩展为检测其他BDF模式,例如,对大量(随机)用户名进行扫描的单个IP.

  • 好的.谢谢!如果可以,为什么不使用处理程序的机制,例如AuthenticationFailureHandler?我的意思是,为什么使用监听器而不是处理程序?任何利弊? (2认同)
  • 您还应该知道锁定受攻击的帐户意味着使您的服务成为可管理的.众所周知的例子是:你提供拍卖服务,鲍勃想买一些位置并攻击爱丽丝的账户,所以爱丽丝试图恢复她的账户而不是下注,而鲍勃得到这个位置.即使是临时(5秒)锁也可能会阻止Alice根据需要使用该服务. (2认同)

And*_*gin 11

您还应该知道锁定受攻击的帐户意味着使您的服务成为可管理的.

众所周知的例子是:你提供拍卖服务,鲍勃想买一些位置并攻击爱丽丝的账户,所以爱丽丝试图恢复她的账户而不是下注,而鲍勃得到这个位置.即使是临时(5秒)锁也可能会阻止Alice根据需要使用该服务.

  • 我想upvote,但这是一个评论,而不是一个答案. (2认同)