From 29f9d13bff2d921c27bc1bbd2295c4094e4e325f Mon Sep 17 00:00:00 2001 From: Ravi Shanigarapu Date: Fri, 23 May 2025 11:56:39 +0530 Subject: [PATCH 1/8] null check and logger added --- .../java/com/iemr/common/utils/JwtUserIdValidationFilter.java | 1 + src/main/java/com/iemr/common/utils/RestTemplateUtil.java | 1 + .../java/com/iemr/common/utils/http/HTTPRequestInterceptor.java | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index adc054dc..2dff1792 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -87,6 +87,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo logger.info("User-Agent: " + userAgent); if (userAgent != null && isMobileClient(userAgent) && authHeader != null) { try { + logger.info("Common-API incoming userAget : "+userAgent); UserAgentContext.setUserAgent(userAgent); filterChain.doFilter(servletRequest, servletResponse); } finally { diff --git a/src/main/java/com/iemr/common/utils/RestTemplateUtil.java b/src/main/java/com/iemr/common/utils/RestTemplateUtil.java index e491e59a..35afc7d0 100644 --- a/src/main/java/com/iemr/common/utils/RestTemplateUtil.java +++ b/src/main/java/com/iemr/common/utils/RestTemplateUtil.java @@ -36,6 +36,7 @@ public static HttpEntity createRequestEntity(Object body, String authori MultiValueMap headers = new LinkedMultiValueMap<>(); headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8"); if(null != UserAgentContext.getUserAgent()) { + logger.info("Common-API getting User-Agent as : "+UserAgentContext.getUserAgent()); headers.add(HttpHeaders.USER_AGENT, UserAgentContext.getUserAgent()); } headers.add(HttpHeaders.AUTHORIZATION, authorization); diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index 59189742..63bf2055 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -150,7 +150,7 @@ public void postHandle(HttpServletRequest request, HttpServletResponse response, else authorization = postAuth; logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization); - if (authorization != null) { + if (authorization != null || !authorization.isEmpty()) { sessionObject.updateSessionObject(authorization, sessionObject.getSessionObject(authorization)); } } catch (Exception e) { From 99218595bca3c5e0307d3554f48920a962551a6e Mon Sep 17 00:00:00 2001 From: Ravi Shanigarapu Date: Fri, 23 May 2025 12:44:32 +0530 Subject: [PATCH 2/8] Redis issue --- .../utils/http/HTTPRequestInterceptor.java | 3 +- .../common/utils/response/OutputResponse.java | 32 ++++++++---------- .../utils/sessionobject/SessionObject.java | 33 ++++++++++++++----- 3 files changed, 40 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java index 63bf2055..23b0af62 100644 --- a/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java +++ b/src/main/java/com/iemr/common/utils/http/HTTPRequestInterceptor.java @@ -150,7 +150,8 @@ public void postHandle(HttpServletRequest request, HttpServletResponse response, else authorization = postAuth; logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization); - if (authorization != null || !authorization.isEmpty()) { + + if (authorization != null && !authorization.equals("")) { sessionObject.updateSessionObject(authorization, sessionObject.getSessionObject(authorization)); } } catch (Exception e) { diff --git a/src/main/java/com/iemr/common/utils/response/OutputResponse.java b/src/main/java/com/iemr/common/utils/response/OutputResponse.java index a4edb8d1..4b0a33be 100644 --- a/src/main/java/com/iemr/common/utils/response/OutputResponse.java +++ b/src/main/java/com/iemr/common/utils/response/OutputResponse.java @@ -59,26 +59,22 @@ public class OutputResponse private static final String RESPONSE = "{\"response\":\"$$STRING\"}"; private static final String RESPONSE_VALUE = "$$STRING"; - public void setResponse(String message) - { + public void setResponse(String message) { JsonArray ja = null; - try - { - Object obj = new JsonParser().parse(message); - if (obj instanceof JsonArray) - { - ja = (JsonArray) obj; - this.data = ja; - } else if (obj instanceof JsonObject) - { - this.data = obj; - } else - { - this.data = new JsonParser().parse(RESPONSE.replace(RESPONSE_VALUE, message)); - // this.data = message; + try { + if (null != message) { + Object obj = new JsonParser().parse(message); + if (obj instanceof JsonArray) { + ja = (JsonArray) obj; + this.data = ja; + } else if (obj instanceof JsonObject) { + this.data = obj; + } else { + this.data = new JsonParser().parse(RESPONSE.replace(RESPONSE_VALUE, message)); + // this.data = message; + } } - } catch (Exception exe) - { + } catch (Exception exe) { this.data = message; this.data = new JsonParser().parse(RESPONSE.replace(RESPONSE_VALUE, message)); } diff --git a/src/main/java/com/iemr/common/utils/sessionobject/SessionObject.java b/src/main/java/com/iemr/common/utils/sessionobject/SessionObject.java index ad8da60b..48a50684 100644 --- a/src/main/java/com/iemr/common/utils/sessionobject/SessionObject.java +++ b/src/main/java/com/iemr/common/utils/sessionobject/SessionObject.java @@ -59,20 +59,28 @@ public SessionObject() { public String getSessionObject(String key) throws RedisSessionException { Boolean extendExpirationTime = ConfigProperties.getExtendExpiryTime(); Integer sessionExpiryTime = ConfigProperties.getSessionExpiryTime(); - return objectStore.getObject(key, extendExpirationTime, sessionExpiryTime); + if(null != key && !key.isEmpty()) { + return objectStore.getObject(key, extendExpirationTime, sessionExpiryTime); + } + return null; } public String setSessionObject(String key, String value) throws RedisSessionException { Integer sessionExpiryTime = ConfigProperties.getSessionExpiryTime(); - return objectStore.setObject(key, value, sessionExpiryTime); + if(null != key && !key.isEmpty()) { + return objectStore.setObject(key, value, sessionExpiryTime); + } + return null; } public String updateSessionObject(String key, String value) throws RedisSessionException { Boolean extendExpirationTime = ConfigProperties.getExtendExpiryTime(); Integer sessionExpiryTime = ConfigProperties.getSessionExpiryTime(); - updateConcurrentSessionObject(key, value, extendExpirationTime, sessionExpiryTime); - return objectStore.updateObject(key, value, extendExpirationTime, sessionExpiryTime); - + if(null != key && !key.isEmpty()) { + updateConcurrentSessionObject(key, value, extendExpirationTime, sessionExpiryTime); + return objectStore.updateObject(key, value, extendExpirationTime, sessionExpiryTime); + } + return null; } private void updateConcurrentSessionObject(String key, String value, Boolean extendExpirationTime, @@ -95,7 +103,9 @@ private void updateConcurrentSessionObject(String key, String value, Boolean ext public void deleteSessionObject(String key) { try { logger.info("Deleting key " + key); - objectStore.deleteObject(key); + if(null != key && !key.isEmpty()) { + objectStore.deleteObject(key); + } logger.info("Deleted key " + key); } catch (Exception e) { logger.error("deleteSessionObject failed with error " + e.getMessage(), e); @@ -104,13 +114,18 @@ public void deleteSessionObject(String key) { public String setSessionObjectForChangePassword(String key, String value) throws RedisSessionException { Integer sessionExpiryTime = ConfigProperties.getSessionExpiryTimeForChangePassword(); - return objectStore.setObject(key, value, sessionExpiryTime); + if(null != key && !key.isEmpty()) { + return objectStore.setObject(key, value, sessionExpiryTime); + } + return null; } public String getSessionObjectForChangePassword(String key) throws RedisSessionException { Boolean extendExpirationTime = ConfigProperties.getExtendExpiryTimeForChangePassword(); Integer sessionExpiryTime = ConfigProperties.getSessionExpiryTimeForChangePassword(); - // RedisStorage objectStore = new RedisStorage(); - return objectStore.getObject(key, extendExpirationTime, sessionExpiryTime); + if(null != key && !key.isEmpty()) { + return objectStore.getObject(key, extendExpirationTime, sessionExpiryTime); + } + return null; } } From 04b3d9912ab03100ccbc45ad93e8b95af14bf077 Mon Sep 17 00:00:00 2001 From: Ravi Shanigarapu Date: Tue, 27 May 2025 12:31:45 +0530 Subject: [PATCH 3/8] Jwttoken added for superUserAuthenticate --- .../controller/users/IEMRAdminController.java | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index b4be2989..95c563d3 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -399,7 +399,7 @@ private void createUserMapping(User mUser, JSONObject resMap, JSONObject service @RequestMapping(value = "/superUserAuthenticate", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON) public String superUserAuthenticate( @Param(value = "\"{\\\"userName\\\":\\\"String\\\",\\\"doLogout\\\":\\\"Boolean\\\"}\"") @RequestBody LoginRequestModel m_User, - HttpServletRequest request) { + HttpServletRequest request,HttpServletResponse httpResponse) { OutputResponse response = new OutputResponse(); logger.info("userAuthenticate request "); try { @@ -411,6 +411,9 @@ public String superUserAuthenticate( User mUser = iemrAdminUserServiceImpl.superUserAuthenticate(m_User.getUserName(), decryptPassword); JSONObject resMap = new JSONObject(); JSONObject previlegeObj = new JSONObject(); + String jwtToken = null; + String refreshToken = null; + boolean isMobile = false; if (m_User.getUserName() != null && (m_User.getDoLogout() == null || m_User.getDoLogout() == false)) { String tokenFromRedis = getConcurrentCheckSessionObjectAgainstUser( m_User.getUserName().trim().toLowerCase()); @@ -425,6 +428,35 @@ public String superUserAuthenticate( resMap.put("userID", mUser.getUserID()); resMap.put("isAuthenticated", /* Boolean.valueOf(true) */true); resMap.put("userName", mUser.getUserName()); + jwtToken = jwtUtil.generateToken(m_User.getUserName(), mUser.getUserID().toString()); + + User user = new User(); // Assuming the Users class exists + user.setUserID(mUser.getUserID()); + user.setUserName(mUser.getUserName()); + + String userAgent = request.getHeader("User-Agent"); + isMobile = UserAgentUtil.isMobileDevice(userAgent); + logger.info("UserAgentUtil isMobile : " + isMobile); + + if (isMobile) { + refreshToken = jwtUtil.generateRefreshToken(m_User.getUserName(), user.getUserID().toString()); + logger.debug("Refresh token generated successfully for user: {}", user.getUserName()); + String jti = jwtUtil.getJtiFromToken(refreshToken); + redisTemplate.opsForValue().set( + "refresh:" + jti, + user.getUserID().toString(), + jwtUtil.getRefreshTokenExpiration(), + TimeUnit.MILLISECONDS + ); + } else { + cookieUtil.addJwtTokenToCookie(jwtToken, httpResponse, request); + } + + String redisKey = "user_" + mUser.getUserID(); // Use user ID to create a unique key + + // Store the user in Redis (set a TTL of 30 minutes) + redisTemplate.opsForValue().set(redisKey, user, 30, TimeUnit.MINUTES); + } else { resMap.put("isAuthenticated", /* Boolean.valueOf(false) */false); } From 05065b8377bad4a669b0a82485878023138fbd9f Mon Sep 17 00:00:00 2001 From: Ravi Shanigarapu Date: Tue, 27 May 2025 12:35:11 +0530 Subject: [PATCH 4/8] Null check --- src/main/java/com/iemr/common/utils/RestTemplateUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/utils/RestTemplateUtil.java b/src/main/java/com/iemr/common/utils/RestTemplateUtil.java index 35afc7d0..447ba80f 100644 --- a/src/main/java/com/iemr/common/utils/RestTemplateUtil.java +++ b/src/main/java/com/iemr/common/utils/RestTemplateUtil.java @@ -40,7 +40,9 @@ public static HttpEntity createRequestEntity(Object body, String authori headers.add(HttpHeaders.USER_AGENT, UserAgentContext.getUserAgent()); } headers.add(HttpHeaders.AUTHORIZATION, authorization); - headers.add("JwtToken",requestHeader.getHeader("JwtToken")); + if(null != requestHeader.getHeader("JwtToken")) { + headers.add("JwtToken",requestHeader.getHeader("JwtToken")); + } if(null != jwtTokenFromCookie) { headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie); } From a0ede18b790596bab497c71a92b9c09192913e11 Mon Sep 17 00:00:00 2001 From: Ravi Shanigarapu Date: Tue, 27 May 2025 12:43:11 +0530 Subject: [PATCH 5/8] If mobile returned refresh token --- .../com/iemr/common/controller/users/IEMRAdminController.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 95c563d3..072bf88d 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -473,6 +473,10 @@ public String superUserAuthenticate( if (remoteAddress == null || remoteAddress.trim().length() == 0) { remoteAddress = request.getRemoteAddr(); } + if (isMobile && null != mUser) { + responseObj.put("jwtToken", jwtToken); + responseObj.put("refreshToken", refreshToken); + } responseObj = iemrAdminUserServiceImpl.generateKeyAndValidateIP(responseObj, remoteAddress, request.getRemoteHost()); response.setResponse(responseObj.toString()); From 7eb2a892e65b499a88ac11bad6c09d12b439ebf0 Mon Sep 17 00:00:00 2001 From: Ravi Shanigarapu Date: Tue, 27 May 2025 23:28:39 +0530 Subject: [PATCH 6/8] Force logout jwttoken expiry --- .../com/iemr/common/constant/Constants.java | 1 + .../controller/users/IEMRAdminController.java | 23 ++++++++++-- .../java/com/iemr/common/utils/JwtUtil.java | 9 +++-- .../com/iemr/common/utils/TokenBlacklist.java | 35 +++++++++++++++++++ 4 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/iemr/common/utils/TokenBlacklist.java diff --git a/src/main/java/com/iemr/common/constant/Constants.java b/src/main/java/com/iemr/common/constant/Constants.java index c6f98e02..ebe7d772 100644 --- a/src/main/java/com/iemr/common/constant/Constants.java +++ b/src/main/java/com/iemr/common/constant/Constants.java @@ -11,5 +11,6 @@ public class Constants { public static final String HOLD = "Hold"; public static final String NOT_READY = "Not Ready"; public static final String AUX = "Aux"; + public static final String JWT_TOKEN = "Jwttoken"; } diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index 072bf88d..edb999c6 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -44,6 +44,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.iemr.common.config.encryption.SecurePassword; +import com.iemr.common.constant.Constants; import com.iemr.common.data.users.LoginSecurityQuestions; import com.iemr.common.data.users.M_Role; import com.iemr.common.data.users.ServiceRoleScreenMapping; @@ -56,6 +57,7 @@ import com.iemr.common.service.users.IEMRAdminUserService; import com.iemr.common.utils.CookieUtil; import com.iemr.common.utils.JwtUtil; +import com.iemr.common.utils.TokenBlacklist; import com.iemr.common.utils.encryption.AESUtil; import com.iemr.common.utils.exception.IEMRException; import com.iemr.common.utils.mapper.InputMapper; @@ -933,9 +935,14 @@ public String forceLogout(@RequestBody ForceLogoutRequestModel request, HttpServ try { // Perform the force logout logic iemrAdminUserServiceImpl.forceLogout(request); - + String token = null; + token = getJwtTokenFromCookies(httpRequest); + if(null == token) { + token = httpRequest.getHeader(Constants.JWT_TOKEN); + } + TokenBlacklist.blacklistToken(token); // Extract and invalidate JWT token cookie dynamically from the request - invalidateJwtCookie(httpRequest, response); + // invalidateJwtCookie(httpRequest, response); // Set the response message outputResponse.setResponse("Success"); @@ -944,7 +951,17 @@ public String forceLogout(@RequestBody ForceLogoutRequestModel request, HttpServ } return outputResponse.toString(); } - + private String getJwtTokenFromCookies(HttpServletRequest request) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if (cookie.getName().equalsIgnoreCase("Jwttoken")) { + return cookie.getValue(); + } + } + } + return null; + } private void invalidateJwtCookie(HttpServletRequest request, HttpServletResponse response) { // Get the cookies from the incoming request Cookie[] cookies = request.getCookies(); diff --git a/src/main/java/com/iemr/common/utils/JwtUtil.java b/src/main/java/com/iemr/common/utils/JwtUtil.java index 56e49549..940b6959 100644 --- a/src/main/java/com/iemr/common/utils/JwtUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtUtil.java @@ -57,12 +57,11 @@ private String buildToken(String username, String userId, String tokenType, long } public Claims validateToken(String token) { + if (TokenBlacklist.isTokenBlacklisted(token)) { + return null; + } try { - return Jwts.parser() - .verifyWith(getSigningKey()) - .build() - .parseSignedClaims(token) - .getPayload(); + return Jwts.parser().verifyWith(getSigningKey()).build().parseSignedClaims(token).getPayload(); } catch (ExpiredJwtException ex) { // Handle expired token specifically if needed diff --git a/src/main/java/com/iemr/common/utils/TokenBlacklist.java b/src/main/java/com/iemr/common/utils/TokenBlacklist.java new file mode 100644 index 00000000..d0d0e478 --- /dev/null +++ b/src/main/java/com/iemr/common/utils/TokenBlacklist.java @@ -0,0 +1,35 @@ +package com.iemr.common.utils; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.springframework.beans.factory.annotation.Value; + +public class TokenBlacklist { + @Value("${jwt.blacklist.expiration}") + private static long BLACK_LIST_EXPIRATION_TIME; + + // Store blacklisted tokens (in-memory) + private static Map blacklistedTokens = new HashMap<>(); + + + // Add a token to the blacklist + public static void blacklistToken(String token) { + blacklistedTokens.put(token, BLACK_LIST_EXPIRATION_TIME); + } + + // Check if a token is blacklisted + + public static boolean isTokenBlacklisted(String token) { + Long expiryTime = blacklistedTokens.get(token); + if (expiryTime == null) return false; + if (System.currentTimeMillis() > expiryTime) { + blacklistedTokens.remove(token); + return false; + } + return true; + } + +} From 7ad12c1d38ff1dc34e77b78792140517f72478a5 Mon Sep 17 00:00:00 2001 From: Ravi Shanigarapu Date: Tue, 27 May 2025 23:39:50 +0530 Subject: [PATCH 7/8] Method corrected --- src/main/java/com/iemr/common/utils/TokenBlacklist.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/TokenBlacklist.java b/src/main/java/com/iemr/common/utils/TokenBlacklist.java index d0d0e478..3a292736 100644 --- a/src/main/java/com/iemr/common/utils/TokenBlacklist.java +++ b/src/main/java/com/iemr/common/utils/TokenBlacklist.java @@ -23,9 +23,10 @@ public static void blacklistToken(String token) { // Check if a token is blacklisted public static boolean isTokenBlacklisted(String token) { - Long expiryTime = blacklistedTokens.get(token); - if (expiryTime == null) return false; - if (System.currentTimeMillis() > expiryTime) { + Long expiry = blacklistedTokens.get(token); + if (expiry == null) return false; + // If token is expired, remove it from blacklist and treat as not blacklisted + if (System.currentTimeMillis() > expiry) { blacklistedTokens.remove(token); return false; } From 1d20ed1523a3dfacab562383a48a1f70b6c5dce1 Mon Sep 17 00:00:00 2001 From: Ravi Shanigarapu Date: Wed, 28 May 2025 00:06:18 +0530 Subject: [PATCH 8/8] coderabbit changes --- .../controller/users/IEMRAdminController.java | 5 ++++- .../com/iemr/common/utils/TokenBlacklist.java | 16 +++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java index edb999c6..9eee79fd 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -34,6 +34,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -85,6 +86,8 @@ public class IEMRAdminController { private CookieUtil cookieUtil; @Autowired private RedisTemplate redisTemplate; + @Value("${jwt.blacklist.expiration}") + private static long BLACK_LIST_EXPIRATION_TIME; private AESUtil aesUtil; @@ -940,7 +943,7 @@ public String forceLogout(@RequestBody ForceLogoutRequestModel request, HttpServ if(null == token) { token = httpRequest.getHeader(Constants.JWT_TOKEN); } - TokenBlacklist.blacklistToken(token); + TokenBlacklist.blacklistToken(token,BLACK_LIST_EXPIRATION_TIME); // Extract and invalidate JWT token cookie dynamically from the request // invalidateJwtCookie(httpRequest, response); diff --git a/src/main/java/com/iemr/common/utils/TokenBlacklist.java b/src/main/java/com/iemr/common/utils/TokenBlacklist.java index 3a292736..c60f177a 100644 --- a/src/main/java/com/iemr/common/utils/TokenBlacklist.java +++ b/src/main/java/com/iemr/common/utils/TokenBlacklist.java @@ -4,25 +4,31 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.beans.factory.annotation.Value; public class TokenBlacklist { - @Value("${jwt.blacklist.expiration}") - private static long BLACK_LIST_EXPIRATION_TIME; + // Store blacklisted tokens (in-memory) - private static Map blacklistedTokens = new HashMap<>(); + private static final Map blacklistedTokens = new ConcurrentHashMap<>(); // Add a token to the blacklist - public static void blacklistToken(String token) { - blacklistedTokens.put(token, BLACK_LIST_EXPIRATION_TIME); + public static void blacklistToken(String token ,Long blackListExpirationTime) { + if(token == null || token.trim().isEmpty()) { + return; + } + blacklistedTokens.put(token, System.currentTimeMillis()+ blackListExpirationTime); } // Check if a token is blacklisted public static boolean isTokenBlacklisted(String token) { + if(token == null || token.trim().isEmpty()) { + return false; + } Long expiry = blacklistedTokens.get(token); if (expiry == null) return false; // If token is expired, remove it from blacklist and treat as not blacklisted