I’m trying to implement a Filter using bucket4j to limit the amount of login attempts (intercepted using Burp suite and perform a BRUTE Force Attack) made by an IP address as follows:
@Component
public class RateLimitingFilter extends OncePerRequestFilter {private final ConcurrentHashMap<String, Bucket> ipBuckets = new ConcurrentHashMap<>();
private static final int REQUEST_THRESHOLD = 20;@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
String requestURI = request.getRequestURI();if ("POST".equalsIgnoreCase(request.getMethod()) && request.getQueryString() != null && request.getQueryString().contains("v-r=uidl")&& "/login".equals(requestURI)) { String clientIP = request.getRemoteAddr(); Bucket bucket = ipBuckets.computeIfAbsent(clientIP, this::createBucket); if (bucket.tryConsume(1)) { filterChain.doFilter(request, response); } else { response.setStatus(429); response.getWriter().write("Too many requests. Please try again later."); System.out.println("Rate limit exceeded for IP: " + clientIP); return; } } else { filterChain.doFilter(request, response); }
}
private Bucket createBucket(String key) {
Refill refill = Refill.intervally(REQUEST_THRESHOLD, Duration.ofMinutes(1));
Bandwidth limit = Bandwidth.classic(REQUEST_THRESHOLD, refill);
return Bucket4j.builder().addLimit(limit).build();
}}
The above mechanism applies the filter for all requests which I don’t need. I can’t differentiate between a login POST request with other requests. request.getRequestURI() always returns “/”. How can i get the actual URI which is “/login”? Any suggestions?