I am trying to implement Caffeine cache to avoid brute force login attempts. So that I have a cache with key = IP adress and value = number of login attempts.
I have a service which builds Caffeine cache and some methods to handle login failed and success events. If user gives wrong credentials, then loginFailed(String key)
method is being called. However, getIfPresent(key)
always returns null even after put method is working.
By the way, IP address comes from AuthenticationFailureListener component.
I have tried to Google's Guava Cache, however it is deprecated and replaced with Caffeine.
LoginAttemptService
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;
}
}
}
Above code, I was expecting that when isBlocked(String key)
method is called, it should return number of attempts of given key which is IP address.
Edit: I have located the problem actually. If I do not put expireAfterWrite
to Caffeine builder, it works pretty good. But I have no idea why it is not working.