Add files via upload
This commit is contained in:
parent
cd2728105e
commit
ab9a22d8e7
9 changed files with 382 additions and 314 deletions
|
@ -0,0 +1,68 @@
|
||||||
|
package stirling.software.SPDF.config;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
import io.github.bucket4j.Bandwidth;
|
||||||
|
import io.github.bucket4j.Bucket;
|
||||||
|
import io.github.bucket4j.Bucket4j;
|
||||||
|
import io.github.bucket4j.Refill;
|
||||||
|
import jakarta.servlet.FilterChain;
|
||||||
|
import jakarta.servlet.ServletException;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
@Component
|
||||||
|
public class UserBasedRateLimitingFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
private final Map<String, Bucket> buckets = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
String method = request.getMethod();
|
||||||
|
if (!"POST".equalsIgnoreCase(method)) {
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String identifier;
|
||||||
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
|
||||||
|
if (authentication != null && authentication.isAuthenticated()) {
|
||||||
|
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
|
||||||
|
identifier = userDetails.getUsername();
|
||||||
|
} else {
|
||||||
|
identifier = request.getRemoteAddr(); // Use IP as identifier if not authenticated
|
||||||
|
}
|
||||||
|
|
||||||
|
Bucket userBucket = buckets.computeIfAbsent(identifier, k -> createUserBucket());
|
||||||
|
|
||||||
|
if (userBucket.tryConsume(1)) {
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
} else {
|
||||||
|
response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
|
||||||
|
response.getWriter().write("Rate limit exceeded.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//https://www.baeldung.com/spring-bucket4j
|
||||||
|
private Bucket createUserBucket() {
|
||||||
|
Refill refill = Refill.of(3, Duration.ofDays(1));
|
||||||
|
Bandwidth limit = Bandwidth.classic(3, refill).withInitialTokens(3);
|
||||||
|
return Bucket4j.builder().addLimit(limit).build();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue