From 4e626a5e0a9964c5fef774c8e173da69086e0ed8 Mon Sep 17 00:00:00 2001 From: Vanitha Date: Wed, 17 Dec 2025 15:47:33 +0530 Subject: [PATCH] fix: role based on both jwt and auth token --- .../common/main/WorklistController.java | 52 ++--- .../login/IemrMmuLoginController.java | 59 +++--- .../TeleConsultationController.java | 16 +- .../VideoConsultationController.java | 12 +- .../java/com/iemr/tm/utils/CookieUtil.java | 9 +- .../mapper/RoleAuthenticationFilter.java | 192 ++++++++++++------ 6 files changed, 219 insertions(+), 121 deletions(-) diff --git a/src/main/java/com/iemr/tm/controller/common/main/WorklistController.java b/src/main/java/com/iemr/tm/controller/common/main/WorklistController.java index a5bf46a4..ad2c84c7 100644 --- a/src/main/java/com/iemr/tm/controller/common/main/WorklistController.java +++ b/src/main/java/com/iemr/tm/controller/common/main/WorklistController.java @@ -35,21 +35,19 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.iemr.tm.data.benFlowStatus.BeneficiaryFlowStatus; import com.iemr.tm.service.common.transaction.CommonDoctorServiceImpl; import com.iemr.tm.service.common.transaction.CommonNurseServiceImpl; import com.iemr.tm.service.common.transaction.CommonServiceImpl; -import com.iemr.tm.utils.CookieUtil; import com.iemr.tm.utils.JwtUtil; import com.iemr.tm.utils.mapper.InputMapper; import com.iemr.tm.utils.response.OutputResponse; +import org.springframework.security.core.Authentication; import io.lettuce.core.dynamic.annotation.Param; import io.swagger.v3.oas.annotations.Operation; -import jakarta.servlet.http.HttpServletRequest; @RestController @RequestMapping(value = "/common", headers = "Authorization", consumes = "application/json", produces = "application/json") @@ -711,18 +709,22 @@ public String getBeneficiaryCaseSheetHistory( @Operation(summary = "Get teleconsultation specialist worklist") @GetMapping(value = { "/getTCSpecialistWorklist/{providerServiceMapID}/{serviceID}" }) public String getTCSpecialistWorkListNew(@PathVariable("providerServiceMapID") Integer providerServiceMapID, - @PathVariable("serviceID") Integer serviceID, HttpServletRequest request) { + @PathVariable("serviceID") Integer serviceID, Authentication authentication) { OutputResponse response = new OutputResponse(); - try { - String jwtToken = CookieUtil.getJwtTokenFromCookie(request); - String userId = jwtUtil.getUserIdFromToken(jwtToken); - Integer userID=Integer.parseInt(userId); - if (providerServiceMapID != null && userId != null ) { + try { + if (authentication == null || !authentication.isAuthenticated()) { + response.setError(403, "Unauthorized access"); + return response.toString(); + } + + Integer userID = Integer.valueOf(authentication.getPrincipal().toString()); + + if (providerServiceMapID != null && userID != null ) { String s = commonDoctorServiceImpl.getTCSpecialistWorkListNewForTM(providerServiceMapID, userID, serviceID); if (s != null) response.setResponse(s); - } else if(userId == null || jwtToken == null) { + } else if(userID == null ) { response.setError(403, "Unauthorized access!"); } else { logger.error("Invalid request"); @@ -742,20 +744,21 @@ public String getTCSpecialistWorkListNew(@PathVariable("providerServiceMapID") I "/getTCSpecialistWorklistPatientApp/{providerServiceMapID}/{serviceID}/{vanID}" }) public String getTCSpecialistWorkListNewPatientApp( @PathVariable("providerServiceMapID") Integer providerServiceMapID, - @PathVariable("serviceID") Integer serviceID, @PathVariable("vanID") Integer vanID, HttpServletRequest request) { + @PathVariable("serviceID") Integer serviceID, @PathVariable("vanID") Integer vanID, Authentication authentication) { OutputResponse response = new OutputResponse(); try { - String jwtToken = CookieUtil.getJwtTokenFromCookie(request); - String userId = jwtUtil.getUserIdFromToken(jwtToken); - Integer userID=Integer.parseInt(userId); + if (authentication == null || !authentication.isAuthenticated()) { + response.setError(403, "Unauthorized access"); + return response.toString(); + } + + Integer userID = Integer.valueOf(authentication.getPrincipal().toString()); if (providerServiceMapID != null && userID != null) { String s = commonDoctorServiceImpl.getTCSpecialistWorkListNewForTMPatientApp(providerServiceMapID, userID, serviceID, vanID); if (s != null) response.setResponse(s); - } else if(userId == null || jwtToken == null) { - response.setError(403, "Unauthorized access!"); - } else { + } else { logger.error("Invalid request"); response.setError(5000, "Invalid request"); } @@ -773,21 +776,22 @@ public String getTCSpecialistWorkListNewPatientApp( "/getTCSpecialistWorklistFutureScheduled/{providerServiceMapID}/{serviceID}" }) public String getTCSpecialistWorklistFutureScheduled( @PathVariable("providerServiceMapID") Integer providerServiceMapID, - @PathVariable("serviceID") Integer serviceID, HttpServletRequest request) { + @PathVariable("serviceID") Integer serviceID, Authentication authentication) { OutputResponse response = new OutputResponse(); try { - String jwtToken = CookieUtil.getJwtTokenFromCookie(request); - String userId = jwtUtil.getUserIdFromToken(jwtToken); - Integer userID=Integer.parseInt(userId); + if (authentication == null || !authentication.isAuthenticated()) { + response.setError(403, "Unauthorized access"); + return response.toString(); + } + + Integer userID = Integer.valueOf(authentication.getPrincipal().toString()); if (providerServiceMapID != null && userID != null ) { String s = commonDoctorServiceImpl.getTCSpecialistWorkListNewFutureScheduledForTM(providerServiceMapID, userID, serviceID); if (s != null) response.setResponse(s); - } else if(userId == null || jwtToken == null) { - response.setError(403, "Unauthorized access!"); - } else { + } else { logger.error("Invalid request"); response.setError(5000, "Invalid request"); } diff --git a/src/main/java/com/iemr/tm/controller/login/IemrMmuLoginController.java b/src/main/java/com/iemr/tm/controller/login/IemrMmuLoginController.java index 0f11a27a..eb64b2c5 100644 --- a/src/main/java/com/iemr/tm/controller/login/IemrMmuLoginController.java +++ b/src/main/java/com/iemr/tm/controller/login/IemrMmuLoginController.java @@ -36,17 +36,17 @@ import com.iemr.tm.controller.registrar.main.RegistrarController; import com.iemr.tm.service.login.IemrMmuLoginServiceImpl; -import com.iemr.tm.utils.CookieUtil; import com.iemr.tm.utils.JwtUtil; import com.iemr.tm.utils.mapper.InputMapper; import com.iemr.tm.utils.response.OutputResponse; +import org.springframework.security.core.Authentication; import io.swagger.v3.oas.annotations.Operation; import jakarta.servlet.http.HttpServletRequest; @RestController @RequestMapping(value = "/user", headers = "Authorization", consumes = "application/json", produces = "application/json") -@PreAuthorize("hasRole('NURSE') || hasRole('PHARMACIST') || hasRole('LABTECHNICIAN') || hasRole('REGISTRAR') || hasRole('DATASYNC') || hasRole('DATA_SYNC') || hasRole('DOCTOR') || hasRole('LAB_TECHNICIAN') || hasRole('TC_SPECIALIST') || hasRole('ONCOLOGIST') || hasRole('RADIOLOGIST')") +@PreAuthorize("hasRole('NURSE') || hasRole('PHARMACIST') || hasRole('LABTECHNICIAN') || hasRole('REGISTRAR') || hasRole('DATASYNC') || hasRole('DATA_SYNC') || hasRole('DOCTOR') || hasRole('LAB_TECHNICIAN') || hasRole('TC_SPECIALIST') || hasRole('ONCOLOGIST') || hasRole('RADIOLOGIST') || hasRole('ASHA')") public class IemrMmuLoginController { private Logger logger = LoggerFactory.getLogger(RegistrarController.class); @@ -66,17 +66,21 @@ public void setIemrMmuLoginServiceImpl(IemrMmuLoginServiceImpl iemrMmuLoginServi @Operation(summary = "Get user service point van details") @PostMapping(value = "/getUserServicePointVanDetails", produces = { "application/json" }) - public String getUserServicePointVanDetails(@RequestBody String comingRequest, HttpServletRequest request) { + public String getUserServicePointVanDetails(@RequestBody String comingRequest, Authentication authentication) { OutputResponse response = new OutputResponse(); try { - String jwtToken = CookieUtil.getJwtTokenFromCookie(request); - String userId = jwtUtil.getUserIdFromToken(jwtToken); - Integer userID=Integer.parseInt(userId); + if (authentication == null || !authentication.isAuthenticated()) { + response.setError(403, "Unauthorized access"); + return response.toString(); + } + + Integer userID = Integer.valueOf(authentication.getPrincipal().toString()); + JSONObject obj = new JSONObject(comingRequest); logger.info("getUserServicePointVanDetails request " + comingRequest); - if (userId == null || jwtToken ==null) { + if (userID == null) { response.setError(403, "Unauthorized access: Missing or invalid token"); return response.toString(); } @@ -114,30 +118,31 @@ public String getServicepointVillages(@RequestBody String comingRequest) { @Operation(summary = "Get user service point van details") @PostMapping(value = "/getUserVanSpDetails", produces = { "application/json" }) - public String getUserVanSpDetails(@RequestBody String comingRequest, HttpServletRequest request) { + public String getUserVanSpDetails(@RequestBody String comingRequest, Authentication authentication) { OutputResponse response = new OutputResponse(); try { - String jwtToken = CookieUtil.getJwtTokenFromCookie(request); - String userId = jwtUtil.getUserIdFromToken(jwtToken); - Integer userID=Integer.parseInt(userId); + if (authentication == null || !authentication.isAuthenticated()) { + response.setError(403, "Unauthorized access"); + return response.toString(); + } - JSONObject obj = new JSONObject(comingRequest); - logger.info("getServicepointVillages request " + comingRequest); - - if (userId !=null && obj.has("providerServiceMapID")) { - String responseData = iemrMmuLoginServiceImpl.getUserVanSpDetails(userID, - obj.getInt("providerServiceMapID")); - response.setResponse(responseData); - } else if(userId == null || jwtToken ==null) { - response.setError(403, "Unauthorized access : Missing or invalid token"); - } else { - response.setError(5000, "Invalid request"); - } - } catch (Exception e) { - response.setError(5000, "Error while getting van and service points data"); - logger.error("getUserVanSpDetails failed with " + e.getMessage(), e); + Integer userID = Integer.valueOf(authentication.getPrincipal().toString()); - } + JSONObject obj = new JSONObject(comingRequest); + logger.info("getUserVanSpDetails request {}", comingRequest); + + if (obj.has("providerServiceMapID")) { + String responseData = iemrMmuLoginServiceImpl.getUserVanSpDetails(userID, obj.getInt("providerServiceMapID")); + + response.setResponse(responseData); + } else { + response.setError(400, "Invalid request"); + } + + } catch (Exception e) { + response.setError(400, "Error while getting van and service points data"); + logger.error("getUserVanSpDetails failed", e); + } logger.info("getUserVanSpDetails response " + response.toString()); return response.toString(); } diff --git a/src/main/java/com/iemr/tm/controller/teleconsultation/TeleConsultationController.java b/src/main/java/com/iemr/tm/controller/teleconsultation/TeleConsultationController.java index 91a1114e..316a5e1a 100644 --- a/src/main/java/com/iemr/tm/controller/teleconsultation/TeleConsultationController.java +++ b/src/main/java/com/iemr/tm/controller/teleconsultation/TeleConsultationController.java @@ -25,13 +25,16 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; + import jakarta.servlet.http.HttpServletRequest; + import com.iemr.tm.utils.CookieUtil; import com.iemr.tm.utils.JwtUtil; @@ -145,19 +148,22 @@ public String createTCRequestForBeneficiary(@RequestBody String requestOBJ, @Req // TC request List @Operation(summary = "Get teleconsultation request list for a specialist") @PostMapping(value = { "/getTCRequestList" }) - public String getTCSpecialistWorkListNew(@RequestBody String requestOBJ, HttpServletRequest request) { + public String getTCSpecialistWorkListNew(@RequestBody String requestOBJ, Authentication authentication) { OutputResponse response = new OutputResponse(); try { - String jwtToken = CookieUtil.getJwtTokenFromCookie(request); - String userId = jwtUtil.getUserIdFromToken(jwtToken); - Integer userID=Integer.parseInt(userId); + if (authentication == null || !authentication.isAuthenticated()) { + response.setError(403, "Unauthorized access"); + return response.toString(); + } + + Integer userID = Integer.valueOf(authentication.getPrincipal().toString()); if (requestOBJ != null) { JsonObject jsnOBJ = new JsonObject(); JsonParser jsnParser = new JsonParser(); JsonElement jsnElmnt = jsnParser.parse(requestOBJ); jsnOBJ = jsnElmnt.getAsJsonObject(); - if (userId != null) { + if (userID != null) { String s = teleConsultationServiceImpl.getTCRequestListBySpecialistIdAndDate( jsnOBJ.get("psmID").getAsInt(), userID, jsnOBJ.get("date").getAsString()); diff --git a/src/main/java/com/iemr/tm/controller/videoconsultationcontroller/VideoConsultationController.java b/src/main/java/com/iemr/tm/controller/videoconsultationcontroller/VideoConsultationController.java index 90243696..5fc51fa2 100644 --- a/src/main/java/com/iemr/tm/controller/videoconsultationcontroller/VideoConsultationController.java +++ b/src/main/java/com/iemr/tm/controller/videoconsultationcontroller/VideoConsultationController.java @@ -24,6 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -32,7 +33,9 @@ import com.iemr.tm.service.videoconsultation.VideoConsultationService; import com.iemr.tm.utils.response.OutputResponse; + import jakarta.servlet.http.HttpServletRequest; + import com.iemr.tm.utils.CookieUtil; import com.iemr.tm.utils.JwtUtil; @@ -53,13 +56,16 @@ public class VideoConsultationController { @Operation(summary = "Login to video consultation service") @GetMapping(value = "/login/{userID}", headers = "Authorization", produces = { "application/json" }) - public String login(@PathVariable("userID") Long userID, HttpServletRequest request) { + public String login(@PathVariable("userID") Long userID, Authentication authentication) { OutputResponse response = new OutputResponse(); try { - String jwtToken = CookieUtil.getJwtTokenFromCookie(request); - String userId = jwtUtil.getUserIdFromToken(jwtToken); + if (authentication == null || !authentication.isAuthenticated()) { + response.setError(403, "Unauthorized access"); + return response.toString(); + } + String userId = authentication.getPrincipal().toString(); if(userID.toString().equals(userId)) { String createdData = videoConsultationService.login(userID); diff --git a/src/main/java/com/iemr/tm/utils/CookieUtil.java b/src/main/java/com/iemr/tm/utils/CookieUtil.java index b20d6256..1faea949 100644 --- a/src/main/java/com/iemr/tm/utils/CookieUtil.java +++ b/src/main/java/com/iemr/tm/utils/CookieUtil.java @@ -12,7 +12,7 @@ @Service public class CookieUtil { - public Optional getCookieValue(HttpServletRequest request, String cookieName) { + public static Optional getCookieValue(HttpServletRequest request, String cookieName) { Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { @@ -36,4 +36,11 @@ public static String getJwtTokenFromCookie(HttpServletRequest request) { .findFirst() .orElse(null); } + + /** + * Get auth token from cookies (for legacy support) + */ + public static String getAuthTokenFromCookie(HttpServletRequest request) { + return getCookieValue(request, "Authorization").orElse(null); + } } diff --git a/src/main/java/com/iemr/tm/utils/mapper/RoleAuthenticationFilter.java b/src/main/java/com/iemr/tm/utils/mapper/RoleAuthenticationFilter.java index 68effd1d..168f684c 100644 --- a/src/main/java/com/iemr/tm/utils/mapper/RoleAuthenticationFilter.java +++ b/src/main/java/com/iemr/tm/utils/mapper/RoleAuthenticationFilter.java @@ -4,6 +4,9 @@ import java.util.Objects; import java.util.stream.Collectors; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; @@ -12,24 +15,24 @@ import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; -import com.iemr.tm.service.common.master.CommonMasterServiceImpl; import com.iemr.tm.utils.CookieUtil; import com.iemr.tm.utils.JwtAuthenticationUtil; import com.iemr.tm.utils.JwtUtil; import com.iemr.tm.utils.redis.RedisStorage; import io.jsonwebtoken.Claims; -import io.jsonwebtoken.io.IOException; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; -import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @Component public class RoleAuthenticationFilter extends OncePerRequestFilter { - - @Autowired + + private static final Logger logger + = LoggerFactory.getLogger(RoleAuthenticationFilter.class); + + @Autowired private JwtUtil jwtUtil; @Autowired @@ -38,59 +41,126 @@ public class RoleAuthenticationFilter extends OncePerRequestFilter { @Autowired private JwtAuthenticationUtil userService; - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException, java.io.IOException { - List authRoles = null; - try { - String jwtFromCookie = CookieUtil.getJwtTokenFromCookie(request); - String jwtFromHeader = request.getHeader("Jwttoken"); - - String jwtToken = jwtFromCookie != null ? jwtFromCookie : jwtFromHeader; - if(null == jwtToken || jwtToken.trim().isEmpty()) { - filterChain.doFilter(request, response); - return; - } - Claims claims = jwtUtil.validateToken(jwtToken); - if(null == claims) { - filterChain.doFilter(request, response); - return; - } - Object userIdObj = claims.get("userId"); - String userId = userIdObj != null ? userIdObj.toString() : null; - if (null == userId || userId.trim().isEmpty()) { - filterChain.doFilter(request, response); - return; - } - Long userIdLong; - try { - userIdLong=Long.valueOf(userId); - }catch (NumberFormatException ex) { - filterChain.doFilter(request, response); - return; - } - authRoles = redisService.getUserRoleFromCache(userIdLong); - if (authRoles == null || authRoles.isEmpty()) { - List roles = userService.getUserRoles(userIdLong); // assuming this returns multiple roles - authRoles = roles.stream() - .filter(Objects::nonNull) - .map(String::trim) - .map(role -> "ROLE_" + role.toUpperCase().replace(" ", "_")) - .collect(Collectors.toList()); - redisService.cacheUserRoles(userIdLong, authRoles); - } - - List authorities = authRoles.stream() - .map(SimpleGrantedAuthority::new) - .collect(Collectors.toList()); - - UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(userId, null, authorities); - SecurityContextHolder.getContext().setAuthentication(auth); - } catch (Exception e) { - SecurityContextHolder.clearContext(); - } finally { - filterChain.doFilter(request, response); - } - - } -} \ No newline at end of file + @Override + protected void doFilterInternal(HttpServletRequest request, + HttpServletResponse response, + FilterChain filterChain) + throws ServletException, java.io.IOException { + + try { + Long userId = null; + + /* ======================= + * TRY JWT TOKEN FIRST + * ======================= */ + String jwtToken + = CookieUtil.getJwtTokenFromCookie(request) != null + ? CookieUtil.getJwtTokenFromCookie(request) + : request.getHeader("Jwttoken"); + + if (jwtToken != null && !jwtToken.isBlank()) { + Claims claims = jwtUtil.validateToken(jwtToken); + if (claims != null && claims.get("userId") != null) { + userId = Long.valueOf(claims.get("userId").toString()); + logger.info("UserId resolved from JWT: {}", userId); + } + } + + /* ================================= + * FALLBACK → LEGACY AUTH + REDIS + * ================================= */ + if (userId == null) { + String authToken = resolveAuthToken(request); + logger.info("Resolved authToken: {}", authToken); + + if (authToken != null && !authToken.isBlank()) { + String sessionJson = null; + try { + sessionJson = redisService.getObject(authToken, true, 100000); + } catch (Exception ex) { + logger.warn("No Redis session found for authToken: {}", authToken); + filterChain.doFilter(request, response); + return; + } + + if (sessionJson != null && !sessionJson.isBlank()) { + JSONObject json = new JSONObject(sessionJson); + + if (json.has("userID")) { + userId = json.getLong("userID"); + logger.info("UserId resolved from Redis: {}", userId); + } + } + } + } + + /* ======================= + * NO USER → SKIP + * ======================= */ + if (userId == null) { + logger.debug("No userId resolved, skipping authentication"); + filterChain.doFilter(request, response); + return; + } + + /* ======================= + * LOAD USER ROLES + * ======================= */ + List authRoles + = redisService.getUserRoleFromCache(userId); + + if (authRoles == null || authRoles.isEmpty()) { + authRoles = userService.getUserRoles(userId) + .stream() + .filter(Objects::nonNull) + .map(String::trim) + .map(r -> "ROLE_" + r.toUpperCase().replace(" ", "_")) + .collect(Collectors.toList()); + + redisService.cacheUserRoles(userId, authRoles); + } + + /* ======================= + * SET SECURITY CONTEXT + * ======================= */ + List authorities = authRoles.stream() + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + + UsernamePasswordAuthenticationToken authentication + = new UsernamePasswordAuthenticationToken( + userId, null, authorities); + + SecurityContextHolder.getContext() + .setAuthentication(authentication); + + logger.info("Authentication set for userId {}", userId); + + } catch (Exception e) { + logger.error("Authentication error", e); + SecurityContextHolder.clearContext(); + } + + filterChain.doFilter(request, response); + } + + /* ======================= + * AUTH TOKEN RESOLVER + * ======================= */ + private String resolveAuthToken(HttpServletRequest request) { + + String token = request.getHeader("Authorization"); + + if (token == null || token.isBlank()) { + token = request.getHeader("AuthToken"); + } + if (token == null || token.isBlank()) { + token = request.getHeader("X-Auth-Token"); + } + if (token == null || token.isBlank()) { + token = CookieUtil.getCookieValue(request, "Authorization") + .orElse(null); + } + return token; + } +}