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

Posted

技术标签:

【中文标题】Spring Security:如何实现暴力检测(BFD)?【英文标题】:Spring Security: how to implement Brute Force Detection (BFD)? 【发布时间】:2011-02-10 12:05:53 【问题描述】:

我的 Web 应用程序安全性由 Spring Security 3.02 处理,但我找不到任何对暴力检测的现成支持。

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

使用 Spring Security 实现这一点的最佳方法是什么?是否有任何机构有这方面的示例代码或最佳实践?

【问题讨论】:

【参考方案1】:

推出自己的 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。

【讨论】:

请注意,并非所有登录方法都使用 AuthenticationSuccessEvent。您可能还想查看 InteractiveAuthenticationSuccessEvent。 好一个。谢谢!如果可以,您为什么不使用处理程序的机制,例如 AuthenticationFailureHandler?我的意思是,为什么使用侦听器而不是处理程序?有什么优点/缺点? 您还应该知道,锁定被攻击的帐户意味着使您的服务处于 DOSable 状态。众所周知的例子是:您提供拍卖服务,Bob 想要购买一些头寸并攻击 Alice 的账户,因此 Alice 没有下注,而是尝试在 Bob 获得头寸时恢复她的账户。即使是临时(5 秒)锁定也可能会阻止 Alice 按她的需要使用该服务。 我相信每分钟最多登录尝试次数的系统更加用户友好。如果用户尝试登录太快,它总是会失败。这可能需要在身份验证之前使用处理程序。有谁知道该怎么做? @Kdeveloper,我尝试使用相同的代码,但我的失败事件的应用程序侦听器没有被调用。我只是没有为成功事件添加监听器。你能帮帮我吗?【参考方案2】:

您还应该知道,锁定受攻击的帐户意味着使您的服务处于 DOSable 状态。

众所周知的例子是:您提供拍卖服务,Bob 想要购买一些头寸并攻击 Alice 的账户,因此 Alice 没有下注,而是尝试在 Bob 获得头寸时恢复她的账户。即使是临时(5 秒)锁定也可能会阻止 Alice 按她的需要使用该服务。

【讨论】:

那么,在这个场景中,你的建议是什么?

以上是关于Spring Security:如何实现暴力检测(BFD)?的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security 入门(1-13)Spring Security - Session管理

Security安全认证 | Spring Boot如何集成Security实现安全认证

我们如何使用带有 Spring 5.0 的最新 spring-security-oauth2 jar 来实现授权服务器?

Spring Boot如何集成Security实现安全认证

如何实现 Openid 连接和 Spring Security

如何创建数据类实现 Spring Security 特定的 UserDetails