From de0b2cbaf73bf079ccf461f873ef4c7bb7d5a8c3 Mon Sep 17 00:00:00 2001 From: Camelia Dumitru Date: Tue, 5 Nov 2024 19:06:44 +0000 Subject: [PATCH 1/3] Added the white list implementation --- .../orcid/api/filters/ApiRateLimitFilter.java | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java b/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java index 2db61a53b1..01f143da2e 100644 --- a/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java +++ b/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java @@ -3,7 +3,9 @@ import java.io.IOException; import java.io.PrintWriter; import java.time.LocalDate; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -14,6 +16,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.LocaleUtils; +import org.apache.commons.lang3.StringUtils; import org.orcid.core.manager.ClientDetailsEntityCacheManager; import org.orcid.core.manager.OrcidSecurityManager; import org.orcid.core.manager.TemplateManager; @@ -88,6 +91,9 @@ public class ApiRateLimitFilter extends OncePerRequestFilter { @Value("${org.orcid.persistence.panoply.papiExceededRate.production:false}") private boolean enablePanoplyPapiExceededRateInProduction; + + @Value("${org.orcid.papi.rate.limit.ip.whiteSpaceSeparatedWhiteList:1.1.1.1 127.0.0.1}") + private String papiWhiteSpaceSeparatedWhiteList; private static final String TOO_MANY_REQUESTS_MSG = "Too Many Requests - You have exceeded the daily allowance of API calls.\\n" + "You can increase your daily quota by registering for and using Public API client credentials " @@ -105,7 +111,7 @@ protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServl if (httpServletRequest.getHeader("Authorization") != null) { tokenValue = httpServletRequest.getHeader("Authorization").replaceAll("Bearer|bearer", "").trim(); } - String ipAddress = httpServletRequest.getRemoteAddr(); + String ipAddress = getClientIpAddress(httpServletRequest); String clientId = null; if (tokenValue != null) { @@ -118,9 +124,11 @@ protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServl boolean isAnonymous = (clientId == null); LocalDate today = LocalDate.now(); - if (isAnonymous) { - LOG.info("ApiRateLimitFilter anonymous request"); - this.rateLimitAnonymousRequest(ipAddress, today, httpServletResponse); + if (isAnonymous ) { + if(!isWhiteListed(ipAddress)) { + LOG.info("ApiRateLimitFilter anonymous request"); + this.rateLimitAnonymousRequest(ipAddress, today, httpServletResponse); + } } else { LOG.info("ApiRateLimitFilter client request with clientId: " + clientId); @@ -250,5 +258,33 @@ private void setPapiRateExceededItemInPanoply(PanoplyPapiDailyRateExceededItem i }); } + + //gets actual client IP address, using the headers that the proxy server ads + private String getClientIpAddress(HttpServletRequest request) { + String ipAddress = request.getHeader("X-FORWARDED-FOR"); + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getHeader("X-REAL-IP"); + } + if (ipAddress == null || ipAddress.isEmpty() || "unknown".equalsIgnoreCase(ipAddress)) { + ipAddress = request.getRemoteAddr(); + } + if (ipAddress != null && ipAddress.contains(",")) { + ipAddress = ipAddress.split(",")[0].trim(); + } + return ipAddress; + } + + private boolean isWhiteListed(String ipAddress) { + List papiIpWhiteList = null; + if(StringUtils.isNotBlank(papiWhiteSpaceSeparatedWhiteList)) { + papiIpWhiteList = Arrays.asList(papiWhiteSpaceSeparatedWhiteList.split("\\s")); + } + + if(papiIpWhiteList != null) { + return papiIpWhiteList.contains(ipAddress); + + } + return false; + } } From 14fcac9befae16190c11329c1923308b5e4bfa0d Mon Sep 17 00:00:00 2001 From: Camelia Dumitru Date: Tue, 5 Nov 2024 19:08:01 +0000 Subject: [PATCH 2/3] kept just 127.0.0.1 as the ip address in the whitelist as default --- .../src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java b/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java index 01f143da2e..271a0bf611 100644 --- a/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java +++ b/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java @@ -92,7 +92,7 @@ public class ApiRateLimitFilter extends OncePerRequestFilter { @Value("${org.orcid.persistence.panoply.papiExceededRate.production:false}") private boolean enablePanoplyPapiExceededRateInProduction; - @Value("${org.orcid.papi.rate.limit.ip.whiteSpaceSeparatedWhiteList:1.1.1.1 127.0.0.1}") + @Value("${org.orcid.papi.rate.limit.ip.whiteSpaceSeparatedWhiteList:127.0.0.1}") private String papiWhiteSpaceSeparatedWhiteList; private static final String TOO_MANY_REQUESTS_MSG = "Too Many Requests - You have exceeded the daily allowance of API calls.\\n" From c72bd10056f73733eb3f5079e2379622116dcc50 Mon Sep 17 00:00:00 2001 From: Camelia Dumitru Date: Tue, 5 Nov 2024 19:10:43 +0000 Subject: [PATCH 3/3] added the Ip address to the info log for anonymous requests --- .../src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java b/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java index 271a0bf611..daa982cae3 100644 --- a/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java +++ b/orcid-pub-web/src/main/java/org/orcid/api/filters/ApiRateLimitFilter.java @@ -126,7 +126,7 @@ protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServl if (isAnonymous ) { if(!isWhiteListed(ipAddress)) { - LOG.info("ApiRateLimitFilter anonymous request"); + LOG.info("ApiRateLimitFilter anonymous request for ip: " + ipAddress); this.rateLimitAnonymousRequest(ipAddress, today, httpServletResponse); }