我的 Web 应用程序安全性由 Spring Security 3.02 处理,但我找不到任何对蛮力检测的开箱即用支持。
我想实现一些应用程序级别的 BFD 保护。例如,通过在数据库 (JPA) 中存储每个用户的失败登录尝试。然后,受攻击的用户帐户可能会获得锁定期或通过电子邮件强制重新激活帐户。
使用 Spring Security 实现这一点的最佳方法是什么?是否有任何机构对此有示例代码或最佳实践?
我的 Web 应用程序安全性由 Spring Security 3.02 处理,但我找不到任何对蛮力检测的开箱即用支持。
我想实现一些应用程序级别的 BFD 保护。例如,通过在数据库 (JPA) 中存储每个用户的失败登录尝试。然后,受攻击的用户帐户可能会获得锁定期或通过电子邮件强制重新激活帐户。
使用 Spring Security 实现这一点的最佳方法是什么?是否有任何机构对此有示例代码或最佳实践?
推出自己的 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();
}
}
}
现在每个身份验证失败都会通知用户。例如,用户增加认证失败计数器并在达到某个阈值时自行停用它。
当用户被正确认证时,下面的监听器将通知用户(例如,谁可以重置它的认证失败计数器):
@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();
}
}
上面的监听器不需要额外的 XML 配置,并且由 Spring 自动拾取(如果它们在 Spring 组件扫描包中)。
根据您的事务配置,如果它们几乎同时发生,此解决方案可能会错过一些失败的登录计数。如果您使用单个 UPDATE 查询而不是加载用户然后保存更改来更新计数器,则可以防止这种情况发生。
上面的侦听器也可以扩展以检测其他 BDF 模式,例如对大量(随机)用户名进行扫描的单个 IP。
您还应该知道锁定受攻击的帐户意味着使您的服务可用。
众所周知的例子是:您提供拍卖服务,Bob 想要购买一些头寸并攻击 Alice 的账户,所以 Alice 没有下注,而是尝试在 Bob 获得头寸时恢复她的账户。即使是临时(5 秒)锁定也可能会阻止 Alice 按她的需要使用该服务。