0

我正在尝试实现咖啡因缓存以避免暴力登录尝试。这样我就有了一个缓存,其中键 = 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使用咖啡因生成器,它会很好用。但我不知道为什么它不起作用。

4

0 回答 0