Class LoginLockout

java.lang.Object
io.leandev.appfuse.security.lockout.LoginLockout
All Implemented Interfaces:
org.springframework.security.core.userdetails.UserDetailsChecker

public class LoginLockout extends Object implements org.springframework.security.core.userdetails.UserDetailsChecker

登入失敗鎖定

完全走 Spring Security 既有機制,不包裝 AuthenticationProvider

  • 計數:監聽 AuthenticationFailureBadCredentialsEventAuthenticationSuccessEvent (框架的認證事件;與哪個 provider 認證無關)
  • 把關:實作 UserDetailsChecker,掛在 DaoAuthenticationProvidersetPreAuthenticationChecks(...)——Spring 為帳號狀態檢查預留的插槽

接線(消費端組態):

var lockout = new LoginLockout(attemptCache, 5, Duration.ofMinutes(1));
AuthenticationManager manager = DaoAuthenticationManagers
        .builder(userDetailsService, passwordEncoder, eventPublisher)
        .preAuthenticationChecks(lockout) // 把關;builder 同時保證認證事件發布
        .build();

鎖定時長:達閾值起以 step 遞增——閾值當次 = 1 × step,之後每多失敗一次多 1 × step。 需要別的曲線(固定時長、指數退避)覆寫 lockoutDuration(int),不需要另一個政策類。

鎖定中的帳號由本類拋 LockoutExceptionApplicationException 家族,帶失敗次數與剩餘 分鐘),先於 Spring 的帳號狀態旗標檢查;未鎖定則委派 AccountStatusUserDetailsChecker 做標準旗標檢查(disabled/expired/locked)。

  • Constructor Summary

    Constructors
    Constructor
    Description
    LoginLockout(Cache<String, AttemptRecord> cache, int threshold, Duration step)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    check(org.springframework.security.core.userdetails.UserDetails user)
    認證前檢查:鎖定中則拒絕,否則走標準帳號狀態檢查
    void
    clear(String username)
    解除鎖定並清除失敗記錄(供帳號管理面的「解鎖」操作)
    protected Duration
    lockoutDuration(int failureCount)
    依失敗次數計算鎖定時長;覆寫此方法即可換成固定時長或指數退避
    void
    onFailure(org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent event)
    帳密錯誤:累計失敗,達閾值即設鎖定到期時間
    void
    onSuccess(org.springframework.security.authentication.event.AuthenticationSuccessEvent event)
    認證成功:清除記錄

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • LoginLockout

      public LoginLockout(Cache<String, AttemptRecord> cache, int threshold, Duration step)
      Parameters:
      cache - 失敗記錄快取(TTI 過期由快取本身承擔)
      threshold - 觸發鎖定的連續失敗次數
      step - 鎖定時長的遞增單位
  • Method Details

    • check

      public void check(org.springframework.security.core.userdetails.UserDetails user)
      認證前檢查:鎖定中則拒絕,否則走標準帳號狀態檢查
      Specified by:
      check in interface org.springframework.security.core.userdetails.UserDetailsChecker
    • onFailure

      @EventListener public void onFailure(org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent event)
      帳密錯誤:累計失敗,達閾值即設鎖定到期時間
    • onSuccess

      @EventListener public void onSuccess(org.springframework.security.authentication.event.AuthenticationSuccessEvent event)
      認證成功:清除記錄
    • clear

      public void clear(String username)
      解除鎖定並清除失敗記錄(供帳號管理面的「解鎖」操作)
    • lockoutDuration

      protected Duration lockoutDuration(int failureCount)
      依失敗次數計算鎖定時長;覆寫此方法即可換成固定時長或指數退避
      Parameters:
      failureCount - 連續失敗次數(≥ threshold)