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:
- 計數:監聽
AuthenticationFailureBadCredentialsEvent/AuthenticationSuccessEvent(框架的認證事件;與哪個 provider 認證無關) - 把關:實作
UserDetailsChecker,掛在DaoAuthenticationProvider的setPreAuthenticationChecks(...)——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),不需要另一個政策類。
鎖定中的帳號由本類拋 LockoutException(ApplicationException 家族,帶失敗次數與剩餘
分鐘),先於 Spring 的帳號狀態旗標檢查;未鎖定則委派 AccountStatusUserDetailsChecker
做標準旗標檢查(disabled/expired/locked)。
-
Constructor Summary
ConstructorsConstructorDescriptionLoginLockout(Cache<String, AttemptRecord> cache, int threshold, Duration step) -
Method Summary
Modifier and TypeMethodDescriptionvoidcheck(org.springframework.security.core.userdetails.UserDetails user) 認證前檢查:鎖定中則拒絕,否則走標準帳號狀態檢查void解除鎖定並清除失敗記錄(供帳號管理面的「解鎖」操作)protected DurationlockoutDuration(int failureCount) 依失敗次數計算鎖定時長;覆寫此方法即可換成固定時長或指數退避voidonFailure(org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent event) 帳密錯誤:累計失敗,達閾值即設鎖定到期時間voidonSuccess(org.springframework.security.authentication.event.AuthenticationSuccessEvent event) 認證成功:清除記錄
-
Constructor Details
-
LoginLockout
- Parameters:
cache- 失敗記錄快取(TTI 過期由快取本身承擔)threshold- 觸發鎖定的連續失敗次數step- 鎖定時長的遞增單位
-
-
Method Details
-
check
public void check(org.springframework.security.core.userdetails.UserDetails user) 認證前檢查:鎖定中則拒絕,否則走標準帳號狀態檢查- Specified by:
checkin interfaceorg.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
解除鎖定並清除失敗記錄(供帳號管理面的「解鎖」操作) -
lockoutDuration
依失敗次數計算鎖定時長;覆寫此方法即可換成固定時長或指數退避- Parameters:
failureCount- 連續失敗次數(≥ threshold)
-