如何限制Spring Security中的登录尝试?

Mic*_*rdt 18 security login spring-security

Spring Security中是否有一些配置或可用模块来限制登录尝试(理想情况下,我希望在后续失败尝试之间等待时间增加)?如果没有,应该使用API​​的哪一部分?

sou*_*ica 16

实现一个AuthenticationFailureHandler,用于更新DB中的计数/时间.我不会指望使用会话,因为攻击者无论如何都不会发送cookie.

  • 不幸的是,很难以这种方式获取Principal(用于其用户名或id),因为getAuthentication和getExtraInformation都已从AuthenticationException中弃用,因此您无法从数据库中获取用户(无需解析HttpServletRequest的参数).使用AuthenticationProvider似乎适用于(下面,类似于Ritesh的suggetsion). (4认同)

Mar*_*idt 13

从Spring 4.2开始,基于注释的事件监听器可用:

@Component
public class AuthenticationEventListener {

    @EventListener
    public void authenticationFailed(AuthenticationFailureBadCredentialsEvent event) {

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

        // update the failed login count for the user
        // ...
    }

}
Run Code Online (Sandbox Code Playgroud)


Rit*_*esh 5

我最近实现了类似的功能,以使用JMX监视登录失败。请在我的问题中(不使用NotificationPublisherAware的Spring中使用发布JMX通知)回答中的代码。身份验证提供程序的身份验证方法的一个方面会更新MBean并与通知侦听器(该问题中未显示的代码)一起使用,以阻止用户和IP,发送警报电子邮件,甚至在失败超过阈值时暂停登录。

编辑
类似于我对问题的回答春季安全性3:将有关身份验证的信息保存在数据库中,我认为捕获身份验证失败事件(而不是自定义处理程序)并将信息存储在数据库中也将起作用,并且将使代码解耦为好。


pau*_*lcm 5

正如Rob Winch在http://forum.springsource.org/showthread.php?108640-Login-attempts-Spring-security中所建议的那样,我只是进行了子类化DaoAuthenticationProvider(也可以使用Ritesh建议的方面来完成)来限制登录失败的次数,但您也可以断言前置条件:

public class LimitingDaoAuthenticationProvider extends DaoAuthenticationProvider {
  @Autowired
  private UserService userService;
    @Override
    public Authentication authenticate(Authentication authentication)
        throws AuthenticationException {
      // Could assert pre-conditions here, e.g. rate-limiting
      // and throw a custom AuthenticationException if necessary

      try {
        return super.authenticate(authentication);
      } catch (BadCredentialsException e) {
        // Will throw a custom exception if too many failed logins have occurred
        userService.recordLoginFailure(authentication);
        throw e;
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

在Spring config XML中,只需引用这个bean:

<beans id="authenticationProvider"   
    class="mypackage.LimitingDaoAuthenticationProvider"
    p:userDetailsService-ref="userDetailsService"
    p:passwordEncoder-ref="passwordEncoder"/>

<security:authentication-manager>
    <security:authentication-provider ref="authenticationProvider"/>
</security:authentication-manager>
Run Code Online (Sandbox Code Playgroud)

请注意,我认为,这依赖于访问的解决方案AuthenticationExceptionauthenticationextraInformation特性(如实施的AuthenticationFailureHandler可能不应该使用),因为这些属性会被弃用(Spring Security的3.1至少).


Xav*_*ury 5

您还可以使用实现 ApplicationListener<AuthenticationFailureBadCredentialsEvent> 的服务来更新数据库中的记录。

请参阅春季应用程序事件。

  • 我发现这种方式比创建自定义身份验证提供程序的其他解决方案要干净得多。从 spring 4.2 开始,这可以通过注释来处理,进一步将类与 Spring Security 框架解耦。 (2认同)