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