我正在尝试实现咖啡因缓存以避免暴力登录尝试。这样我就有了一个缓存,其中键 = IP 地址,值 = 登录尝试次数。
我有一个服务,它构建咖啡因缓存和一些方法来处理登录失败和成功事件。如果用户提供了错误的凭据,则loginFailed(String key)
调用方法。但是,getIfPresent(key)
即使 put 方法有效,也始终返回 null。
顺便说一下,IP 地址来自AuthenticationFailureListener组件。
我曾尝试使用 Google 的 Guava Cache,但它已被弃用并被咖啡因取代。
登录尝试服务
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class LoginAttemptService {
@Value("${captcha.maxAttempt}")
private int MAX_ATTEMPT;
@Value("${captcha.attemptExpirationHour}")
private int ATTEMPT_EXPIRE_DURATION;
private Cache<String, Integer> attemptsCache;
public LoginAttemptService() {
super();
attemptsCache = Caffeine.newBuilder().
expireAfterWrite(ATTEMPT_EXPIRE_DURATION, TimeUnit.HOURS).build();
}
public void loginSucceeded(String key) {
attemptsCache.invalidate(key);
}
public void loginFailed(String key) {
Integer attempts = attemptsCache.getIfPresent(key);
if (attempts != null) {
attempts++;
attemptsCache.put(key, attempts);
} else {
attemptsCache.put(key, 1);
}
}
public boolean isBlocked(String key) {
Integer numberOfAttemps = attemptsCache.getIfPresent(key);
if (numberOfAttemps != null) {
return numberOfAttemps >= MAX_ATTEMPT;
} else {
return false;
}
}
}
上面的代码,我期望当isBlocked(String key)
方法被调用时,它应该返回给定键的尝试次数,即 IP 地址。
编辑:我实际上已经找到了问题。如果我不expireAfterWrite
使用咖啡因生成器,它会很好用。但我不知道为什么它不起作用。