From 1390ab24b5199e6f6fe4720328f431e934203166 Mon Sep 17 00:00:00 2001 From: IN40068837 Date: Mon, 2 Dec 2024 11:38:41 +0530 Subject: [PATCH 01/11] jwt api implementation --- pom.xml | 141 +++++++++--------- src/main/environment/common_ci.properties | 2 +- src/main/environment/common_dev.properties | 1 + .../environment/common_example.properties | 1 + src/main/environment/common_test.properties | 2 +- src/main/environment/common_uat.properties | 2 +- .../users/IEMRAdminUserServiceImpl.java | 18 +++ .../com/iemr/common/utils/CookieUtil.java | 46 ++++++ .../com/iemr/common/utils/FilterConfig.java | 18 +++ .../common/utils/JwtAuthenticationUtil.java | 91 +++++++++++ .../utils/JwtUserIdValidationFilter.java | 110 ++++++++++++++ .../java/com/iemr/common/utils/JwtUtil.java | 78 ++++++++++ 12 files changed, 440 insertions(+), 70 deletions(-) create mode 100644 src/main/java/com/iemr/common/utils/CookieUtil.java create mode 100644 src/main/java/com/iemr/common/utils/FilterConfig.java create mode 100644 src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java create mode 100644 src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java create mode 100644 src/main/java/com/iemr/common/utils/JwtUtil.java diff --git a/pom.xml b/pom.xml index 1606baea..dbcbfde2 100644 --- a/pom.xml +++ b/pom.xml @@ -66,10 +66,10 @@ - - co.elastic.logging - logback-ecs-encoder - 1.3.2 + + co.elastic.logging + logback-ecs-encoder + 1.3.2 @@ -172,28 +172,17 @@ - + org.json json 20231013 - + @@ -201,16 +190,16 @@ quartz 2.5.0-rc1 - - com.fasterxml.jackson.core - jackson-annotations - 2.17.0 - - - com.fasterxml.jackson.core - jackson-core - 2.17.0 - + + com.fasterxml.jackson.core + jackson-annotations + 2.17.0 + + + com.fasterxml.jackson.core + jackson-core + 2.17.0 + com.openkm sdk4j @@ -423,7 +412,7 @@ org.apache.xmlgraphics batik-all - + org.bouncycastle bcpkix-jdk15on @@ -440,7 +429,7 @@ org.apache.santuario xmlsec - + commons-io commons-io @@ -457,40 +446,59 @@ spring-web 6.1.6 - - - javax.ws.rs - javax.ws.rs-api - 2.1.1 - - - - - org.glassfish.jersey.core - jersey-common - 2.30.1 - - - org.glassfish.jersey.core - jersey-server - 2.30.1 - - - - - - org.glassfish.jersey.media - jersey-media-json-processing - 2.30.1 - - - - - org.glassfish.jaxb - jaxb-runtime - 2.3.1 - + + javax.ws.rs + javax.ws.rs-api + 2.1.1 + + + + + org.glassfish.jersey.core + jersey-common + 2.30.1 + + + org.glassfish.jersey.core + jersey-server + 2.30.1 + + + + + + org.glassfish.jersey.media + jersey-media-json-processing + 2.30.1 + + + + + org.glassfish.jaxb + jaxb-runtime + 2.3.1 + + + + io.jsonwebtoken + jjwt-api + 0.11.5 + + + + io.jsonwebtoken + jjwt-impl + 0.11.5 + runtime + + + + io.jsonwebtoken + jjwt-jackson + 0.11.5 + runtime + @@ -560,8 +568,7 @@ ${target-properties} and ${source-properties} - diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index b805767c..5485e928 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -139,4 +139,4 @@ eAusadhaUrl=https://dlc.kar.nic.in/e-services/api/DWInstituteInward eausadhaAuthorization= spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true - +jwt.secret= diff --git a/src/main/environment/common_dev.properties b/src/main/environment/common_dev.properties index e750c067..85c191f5 100644 --- a/src/main/environment/common_dev.properties +++ b/src/main/environment/common_dev.properties @@ -165,4 +165,5 @@ spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true fileBasePath =/Doc +jwt.secret= diff --git a/src/main/environment/common_example.properties b/src/main/environment/common_example.properties index 2af73c8e..21a353fe 100644 --- a/src/main/environment/common_example.properties +++ b/src/main/environment/common_example.properties @@ -109,4 +109,5 @@ eAusadhaUrl=https://dlc.kar.nic.in/e-services/api/DWInstituteInward eausadhaAuthorization= spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true +jwt.secret= diff --git a/src/main/environment/common_test.properties b/src/main/environment/common_test.properties index 6f036adc..31c0c1d4 100644 --- a/src/main/environment/common_test.properties +++ b/src/main/environment/common_test.properties @@ -166,5 +166,5 @@ spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true fileBasePath =/Doc - +jwt.secret= diff --git a/src/main/environment/common_uat.properties b/src/main/environment/common_uat.properties index 0e0e6db4..8f1e0965 100644 --- a/src/main/environment/common_uat.properties +++ b/src/main/environment/common_uat.properties @@ -138,4 +138,4 @@ spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true fileBasePath =/Doc - +jwt.secret= diff --git a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java index ff58fef0..a9a7858d 100644 --- a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java +++ b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java @@ -1171,4 +1171,22 @@ private String toHex(byte[] array) throws NoSuchAlgorithmException { } return hex; } + + public User getUserById(Long userId) throws IEMRException { + try { + // Fetch user from custom repository by userId + User user = iEMRUserRepositoryCustom.findByUserID(userId); + + // Check if user is found + if (user == null) { + throw new IEMRException("User not found with ID: " + userId); + } + + return user; + } catch (Exception e) { + // Log and throw custom exception in case of errors + logger.error("Error fetching user with ID: " + userId, e); + throw new IEMRException("Error fetching user with ID: " + userId, e); + } + } } diff --git a/src/main/java/com/iemr/common/utils/CookieUtil.java b/src/main/java/com/iemr/common/utils/CookieUtil.java new file mode 100644 index 00000000..a68be238 --- /dev/null +++ b/src/main/java/com/iemr/common/utils/CookieUtil.java @@ -0,0 +1,46 @@ +package com.iemr.common.utils; + + +import java.util.Arrays; +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +@Service +public class CookieUtil { + + public Optional getCookieValue(HttpServletRequest request, String cookieName) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if (cookieName.equals(cookie.getName())) { + return Optional.of(cookie.getValue()); + } + } + } + return Optional.empty(); + } + + public void addJwtTokenToCookie(String Jwttoken, HttpServletResponse response) { + // Create a new cookie with the JWT token + Cookie cookie = new Cookie("Jwttoken", Jwttoken); + cookie.setHttpOnly(true); // Prevent JavaScript access for security + cookie.setSecure(true); // Ensure the cookie is sent only over HTTPS + cookie.setMaxAge(60 * 60 * 24); // 1 day expiration time + cookie.setPath("/"); // Make the cookie available for the entire application + response.addCookie(cookie); // Add the cookie to the response + } + + public String getJwtTokenFromCookie(HttpServletRequest request) { + return Arrays.stream(request.getCookies()) + .filter(cookie -> "Jwttoken".equals(cookie.getName())) + .map(Cookie::getValue) + .findFirst() + .orElse(null); + } +} + diff --git a/src/main/java/com/iemr/common/utils/FilterConfig.java b/src/main/java/com/iemr/common/utils/FilterConfig.java new file mode 100644 index 00000000..c9617362 --- /dev/null +++ b/src/main/java/com/iemr/common/utils/FilterConfig.java @@ -0,0 +1,18 @@ +package com.iemr.common.utils; + +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class FilterConfig { + + @Bean + public FilterRegistrationBean jwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil) { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new JwtUserIdValidationFilter(jwtAuthenticationUtil)); + registrationBean.addUrlPatterns("/*"); // Apply filter to all API endpoints + return registrationBean; + } + +} diff --git a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java new file mode 100644 index 00000000..41591745 --- /dev/null +++ b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java @@ -0,0 +1,91 @@ +package com.iemr.common.utils; + +import java.util.Optional; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; + +import com.iemr.common.data.users.User; +import com.iemr.common.service.users.IEMRAdminUserServiceImpl; +import com.iemr.common.utils.exception.IEMRException; + +import io.jsonwebtoken.Claims; +import jakarta.servlet.http.HttpServletRequest; + +@Component +public class JwtAuthenticationUtil { + + @Autowired + private final CookieUtil cookieUtil; + @Autowired + private final JwtUtil jwtUtil; + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Autowired + private IEMRAdminUserServiceImpl iEMRAdminUserServiceImpl; + + public JwtAuthenticationUtil(CookieUtil cookieUtil, JwtUtil jwtUtil) { + this.cookieUtil = cookieUtil; + this.jwtUtil = jwtUtil; + } + + public ResponseEntity validateJwtToken(HttpServletRequest request) { + Optional jwtTokenOpt = cookieUtil.getCookieValue(request, "Jwttoken"); + + if (jwtTokenOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body("Error 401: Unauthorized - JWT Token is not set!"); + } + + String jwtToken = jwtTokenOpt.get(); + + // Validate the token + Claims claims = jwtUtil.validateToken(jwtToken); + if (claims == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Error 401: Unauthorized - Invalid JWT Token!"); + } + + // Extract username from token + String usernameFromToken = claims.getSubject(); + if (usernameFromToken == null || usernameFromToken.isEmpty()) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Error 401: Unauthorized - Username is missing!"); + } + + // Return the username if valid + return ResponseEntity.ok(usernameFromToken); + } + + public boolean validateUserIdAndJwtToken(String jwtToken) throws IEMRException { + try { + // Validate JWT token and extract claims + Claims claims = jwtUtil.validateToken(jwtToken); + + if (claims == null) { + throw new IEMRException("Invalid JWT token."); + } + + String userId = claims.get("userId", String.class); + String tokenUsername = jwtUtil.extractUsername(jwtToken); + + // Fetch user based on userId from the database or cache + User user = iEMRAdminUserServiceImpl.getUserById(Long.parseLong(userId)); + if (user == null) { + throw new IEMRException("Invalid User ID."); + } + + // Check if the token's username matches the user retrieved by userId + if (!user.getUserName().equalsIgnoreCase(tokenUsername)) { + throw new IEMRException("JWT token and User ID mismatch."); + } + + return true; // Valid userId and JWT token + } catch (Exception e) { + logger.error("Validation failed: " + e.getMessage(), e); + throw new IEMRException("Validation error: " + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java new file mode 100644 index 00000000..b1905b2c --- /dev/null +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -0,0 +1,110 @@ +package com.iemr.common.utils; + +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +@Component +public class JwtUserIdValidationFilter implements Filter { + + private final JwtAuthenticationUtil jwtAuthenticationUtil; + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + public JwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil) { + this.jwtAuthenticationUtil = jwtAuthenticationUtil; + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + + String path = request.getRequestURI(); + String contextPath = request.getContextPath(); + logger.info("JwtUserIdValidationFilter invoked for path: " + path); + + // Log cookies for debugging + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if ("userId".equals(cookie.getName())) { + logger.warn("userId found in cookies! Clearing it..."); + clearUserIdCookie(response); // Explicitly remove userId cookie + } + } + } else { + logger.info("No cookies found in the request"); + } + + + // Log headers for debugging + String jwtTokenFromHeader = request.getHeader("Jwttoken"); + logger.info("JWT token from header: " + jwtTokenFromHeader); + + // Skip login and public endpoints + if (path.equals(contextPath + "/user/userAuthenticate") || + path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") || + path.startsWith(contextPath + "/public")) { + logger.info("Skipping filter for path: " + path); + filterChain.doFilter(servletRequest, servletResponse); + return; + } + + try { + // Retrieve JWT token from cookies + String jwtTokenFromCookie = getJwtTokenFromCookies(request); + logger.info("JWT token from cookie: " + jwtTokenFromCookie); + + // Determine which token (cookie or header) to validate + String jwtToken = jwtTokenFromCookie != null ? jwtTokenFromCookie : jwtTokenFromHeader; + if (jwtToken == null) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "JWT token not found in cookies or headers"); + return; + } + + // Validate JWT token and userId + boolean isValid = jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtToken); + + if (isValid) { + // If token is valid, allow the request to proceed + filterChain.doFilter(servletRequest, servletResponse); + } else { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid JWT token"); + } + } catch (Exception e) { + logger.error("Authorization error: ", e); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authorization error: " + e.getMessage()); + } + } + + private String getJwtTokenFromCookies(HttpServletRequest request) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if (cookie.getName().equals("Jwttoken")) { + return cookie.getValue(); + } + } + } + return null; + } + + private void clearUserIdCookie(HttpServletResponse response) { + Cookie cookie = new Cookie("userId", null); + cookie.setPath("/"); + cookie.setMaxAge(0); // Invalidate the cookie + response.addCookie(cookie); + } +} diff --git a/src/main/java/com/iemr/common/utils/JwtUtil.java b/src/main/java/com/iemr/common/utils/JwtUtil.java new file mode 100644 index 00000000..77a7fa2e --- /dev/null +++ b/src/main/java/com/iemr/common/utils/JwtUtil.java @@ -0,0 +1,78 @@ +package com.iemr.common.utils; + +import java.security.Key; +import java.util.Date; +import java.util.function.Function; + +import javax.crypto.spec.SecretKeySpec; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.security.Keys; + +@Component +public class JwtUtil { + + @Value("${jwt.secret}") + private String SECRET_KEY; + + private static final long EXPIRATION_TIME = 24 * 60 * 60 * 1000; // 1 day in milliseconds + + // Generate a key using the secret + private Key getSigningKey() { + if (SECRET_KEY == null || SECRET_KEY.isEmpty()) { + throw new IllegalStateException("JWT secret key is not set in application.properties"); + } + return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + } + + // Generate JWT Token + public String generateToken(String username, String userId) { + Date now = new Date(); + Date expiryDate = new Date(now.getTime() + EXPIRATION_TIME); + + // Include the userId in the JWT claims + return Jwts.builder() + .setSubject(username) + .claim("userId", userId) // Add userId as a claim + .setIssuedAt(now) + .setExpiration(expiryDate) + .signWith(getSigningKey(), SignatureAlgorithm.HS256) + .compact(); + } + + + // Validate and parse JWT Token + public Claims validateToken(String token) { + try { + return Jwts.parserBuilder() + .setSigningKey(getSigningKey()) + .build() + .parseClaimsJws(token) + .getBody(); + } catch (Exception e) { + return null; // Handle token parsing/validation errors + } + } + + public String extractUsername(String token) { + return extractClaim(token, Claims::getSubject); + } + + public T extractClaim(String token, Function claimsResolver) { + final Claims claims = extractAllClaims(token); + return claimsResolver.apply(claims); + } + + private Claims extractAllClaims(String token) { + return Jwts.parserBuilder() + .setSigningKey(getSigningKey()) + .build() + .parseClaimsJws(token) + .getBody(); + } +} \ No newline at end of file From f5e8a5c3908853db050c60fef70ec21a1ac7d926 Mon Sep 17 00:00:00 2001 From: IN40068837 Date: Mon, 2 Dec 2024 13:50:24 +0530 Subject: [PATCH 02/11] version change --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dbcbfde2..b6b538ab 100644 --- a/pom.xml +++ b/pom.xml @@ -503,7 +503,7 @@ - commonapi-v1.0 + commonapi-v3.0.0 org.apache.maven.plugins From d0c29af217347353273f49eb40ecc9249fd36cc7 Mon Sep 17 00:00:00 2001 From: IN40068837 Date: Thu, 5 Dec 2024 15:37:15 +0530 Subject: [PATCH 03/11] Formatting and dependency upgrade --- pom.xml | 12 +- .../controller/users/IEMRAdminController.java | 75 ++++++-- .../common/model/user/LoginRequestModel.java | 16 +- .../com/iemr/common/utils/CookieUtil.java | 57 +++--- .../com/iemr/common/utils/FilterConfig.java | 15 +- .../common/utils/JwtAuthenticationUtil.java | 139 +++++++------- .../utils/JwtUserIdValidationFilter.java | 177 +++++++++--------- .../java/com/iemr/common/utils/JwtUtil.java | 80 ++++---- 8 files changed, 294 insertions(+), 277 deletions(-) diff --git a/pom.xml b/pom.xml index b6b538ab..39538063 100644 --- a/pom.xml +++ b/pom.xml @@ -172,17 +172,11 @@ - - org.json json 20231013 - @@ -483,20 +477,20 @@ io.jsonwebtoken jjwt-api - 0.11.5 + 0.12.6 io.jsonwebtoken jjwt-impl - 0.11.5 + 0.12.6 runtime io.jsonwebtoken jjwt-jackson - 0.11.5 + 0.12.6 runtime 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 317bdf6a..2a5f1ca9 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -29,7 +29,6 @@ import java.util.List; import java.util.Map; - import javax.ws.rs.core.MediaType; import org.json.JSONArray; @@ -37,6 +36,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -62,6 +63,9 @@ import com.iemr.common.model.user.LoginRequestModel; import com.iemr.common.model.user.LoginResponseModel; import com.iemr.common.service.users.IEMRAdminUserService; +import com.iemr.common.utils.CookieUtil; +import com.iemr.common.utils.JwtAuthenticationUtil; +import com.iemr.common.utils.JwtUtil; import com.iemr.common.utils.encryption.AESUtil; import com.iemr.common.utils.exception.IEMRException; import com.iemr.common.utils.mapper.InputMapper; @@ -72,7 +76,9 @@ import io.lettuce.core.dynamic.annotation.Param; import io.swagger.v3.oas.annotations.Operation; +import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; @RequestMapping("/user") @RestController @@ -81,15 +87,20 @@ public class IEMRAdminController { private InputMapper inputMapper = new InputMapper(); private IEMRAdminUserService iemrAdminUserServiceImpl; - + @Autowired + private JwtUtil jwtUtil; + @Autowired + private CookieUtil cookieUtil; + @Autowired + private JwtAuthenticationUtil jwtAuthenticationUtil; + private AESUtil aesUtil; @Autowired public void setAesUtil(AESUtil aesUtil) { - this.aesUtil = aesUtil; + this.aesUtil = aesUtil; } - @Autowired public void setIemrAdminUserService(IEMRAdminUserService iemrAdminUserService) { this.iemrAdminUserServiceImpl = iemrAdminUserService; @@ -125,7 +136,7 @@ public String userAuthenticateNew( @RequestMapping(value = "/userAuthenticate", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON) public String userAuthenticate( @Param(value = "\"{\\\"userName\\\":\\\"String\\\",\\\"password\\\":\\\"String\\\"}\"") @RequestBody LoginRequestModel m_User, - HttpServletRequest request) { + HttpServletRequest request, HttpServletResponse httpResponse) { OutputResponse response = new OutputResponse(); logger.info("userAuthenticate request - " + m_User + " " + m_User.getUserName() + " " + m_User.getPassword()); try { @@ -137,7 +148,8 @@ public String userAuthenticate( JSONObject serviceRoleMap = new JSONObject(); JSONArray serviceRoleList = new JSONArray(); JSONObject previlegeObj = new JSONObject(); - if (m_User.getUserName() != null && (m_User.getDoLogout() == null || m_User.getDoLogout() == false)) { + if (m_User.getUserName() != null && (m_User.getDoLogout() == null || m_User.getDoLogout() == false) + && (m_User.getWithCredentials() != null || m_User.getWithCredentials() == true)) { String tokenFromRedis = getConcurrentCheckSessionObjectAgainstUser( m_User.getUserName().trim().toLowerCase()); if (tokenFromRedis != null) { @@ -148,6 +160,14 @@ public String userAuthenticate( deleteSessionObject(m_User.getUserName().trim().toLowerCase()); } if (mUser.size() == 1) { + String Jwttoken = jwtUtil.generateToken(m_User.getUserName(), mUser.get(0).getUserID().toString()); + logger.info("jwt token is:" + Jwttoken); + + // Set Jwttoken in the response cookie + cookieUtil.addJwtTokenToCookie(Jwttoken, httpResponse); + + resMap.put("Jwttoken", Jwttoken); + logger.info("response coming from jwt:" + resMap); createUserMapping(mUser.get(0), resMap, serviceRoleMultiMap, serviceRoleMap, serviceRoleList, previlegeObj); } else { @@ -269,11 +289,11 @@ private void createUserMapping(User mUser, JSONObject resMap, JSONObject service previlegeObj.getJSONObject(serv).put("agentID", m_UserServiceRoleMapping.getAgentID()); previlegeObj.getJSONObject(serv).put("agentPassword", m_UserServiceRoleMapping.getAgentPassword()); } - JSONArray roles = previlegeObj.getJSONObject(serv).getJSONArray("roles"); + JSONArray roles = previlegeObj.getJSONObject(serv).getJSONArray("roles"); // roles.put(new JSONObject(m_UserServiceRoleMapping.getM_Role().toString())); - JSONObject roleObject = new JSONObject(m_UserServiceRoleMapping.getM_Role().toString()); - roleObject.put("isSanjeevani", m_UserServiceRoleMapping.getIsSanjeevani()); - roles.put(roleObject); + JSONObject roleObject = new JSONObject(m_UserServiceRoleMapping.getM_Role().toString()); + roleObject.put("isSanjeevani", m_UserServiceRoleMapping.getIsSanjeevani()); + roles.put(roleObject); } Iterator keySet = serviceRoleMultiMap.keys(); while (keySet.hasNext()) { @@ -591,8 +611,9 @@ public String getRoleScreenMappingByProviderID( logger.info("getRoleScreenMappingByProviderID"); try { ObjectMapper objectMapper = new ObjectMapper(); - ServiceRoleScreenMapping serviceRoleScreenMapping = objectMapper.readValue(request, ServiceRoleScreenMapping.class); - + ServiceRoleScreenMapping serviceRoleScreenMapping = objectMapper.readValue(request, + ServiceRoleScreenMapping.class); + List mapping = iemrAdminUserServiceImpl .getUserServiceRoleMappingForProvider(serviceRoleScreenMapping.getProviderServiceMapID()); @@ -611,10 +632,9 @@ public String getRoleScreenMappingByProviderID( */) @Operation(summary = "Get users by provider id") @RequestMapping(value = "/getUsersByProviderID", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON, headers = "Authorization") - public String getUsersByProviderID( - @Param(value = "{\"providerServiceMapID\":\"Integer - providerServiceMapID\", " - + "\"RoleID\":\"Optional: Integer - role ID to be filtered\", " - + "\"languageName\":\"Optional: String - languageName\"}") @RequestBody String request) { + public String getUsersByProviderID(@Param(value = "{\"providerServiceMapID\":\"Integer - providerServiceMapID\", " + + "\"RoleID\":\"Optional: Integer - role ID to be filtered\", " + + "\"languageName\":\"Optional: String - languageName\"}") @RequestBody String request) { OutputResponse response = new OutputResponse(); logger.info("getRolesByProviderID request "); try { @@ -887,8 +907,9 @@ public String userAuthenticateBhavya( OutputResponse response = new OutputResponse(); logger.info("userAuthenticate request - " + m_User + " " + m_User.getUserName() + " " + m_User.getPassword()); try { - //String decryptPassword = aesUtil.decrypt("Piramal12Piramal", m_User.getPassword()); - //logger.info("decryptPassword : " + m_User.getPassword()); + // String decryptPassword = aesUtil.decrypt("Piramal12Piramal", + // m_User.getPassword()); + // logger.info("decryptPassword : " + m_User.getPassword()); List mUser = iemrAdminUserServiceImpl.userAuthenticate(m_User.getUserName(), m_User.getPassword()); JSONObject resMap = new JSONObject(); JSONObject serviceRoleMultiMap = new JSONObject(); @@ -934,4 +955,22 @@ public String userAuthenticateBhavya( return response.toString(); } + @GetMapping("/get-jwt-token") + public ResponseEntity getJwtTokenFromCookie(HttpServletRequest httpRequest) { + // Retrieve the cookie named 'jwtToken' + Cookie[] cookies = httpRequest.getCookies(); + + if (cookies != null) { + for (Cookie cookie : cookies) { + if ("jwtToken".equals(cookie.getName())) { + String jwtToken = cookie.getValue(); + // Return the JWT token in the response + return ResponseEntity.ok(jwtToken); + } + } + } + // Return 404 if the token is not found in the cookies + return ResponseEntity.status(HttpStatus.NOT_FOUND).body("JWT token not found"); + } + } diff --git a/src/main/java/com/iemr/common/model/user/LoginRequestModel.java b/src/main/java/com/iemr/common/model/user/LoginRequestModel.java index 770eaeb4..81308b49 100644 --- a/src/main/java/com/iemr/common/model/user/LoginRequestModel.java +++ b/src/main/java/com/iemr/common/model/user/LoginRequestModel.java @@ -25,23 +25,21 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(exclude = { "authKey" }) -public @Data class LoginRequestModel -{ +public @Data class LoginRequestModel { private String userName; private String password; private String authKey; private Boolean doLogout; - - - + private Boolean withCredentials; + public LoginRequestModel() { - + } - //everwell-1097 registration + + // everwell-1097 registration public LoginRequestModel(String userName, String password) { this.userName = userName; this.password = password; } - - + } diff --git a/src/main/java/com/iemr/common/utils/CookieUtil.java b/src/main/java/com/iemr/common/utils/CookieUtil.java index a68be238..e777e6c4 100644 --- a/src/main/java/com/iemr/common/utils/CookieUtil.java +++ b/src/main/java/com/iemr/common/utils/CookieUtil.java @@ -1,6 +1,5 @@ package com.iemr.common.utils; - import java.util.Arrays; import java.util.Optional; @@ -13,34 +12,30 @@ @Service public class CookieUtil { - public Optional getCookieValue(HttpServletRequest request, String cookieName) { - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (Cookie cookie : cookies) { - if (cookieName.equals(cookie.getName())) { - return Optional.of(cookie.getValue()); - } - } - } - return Optional.empty(); - } - - public void addJwtTokenToCookie(String Jwttoken, HttpServletResponse response) { - // Create a new cookie with the JWT token - Cookie cookie = new Cookie("Jwttoken", Jwttoken); - cookie.setHttpOnly(true); // Prevent JavaScript access for security - cookie.setSecure(true); // Ensure the cookie is sent only over HTTPS - cookie.setMaxAge(60 * 60 * 24); // 1 day expiration time - cookie.setPath("/"); // Make the cookie available for the entire application - response.addCookie(cookie); // Add the cookie to the response - } - - public String getJwtTokenFromCookie(HttpServletRequest request) { - return Arrays.stream(request.getCookies()) - .filter(cookie -> "Jwttoken".equals(cookie.getName())) - .map(Cookie::getValue) - .findFirst() - .orElse(null); - } + public Optional getCookieValue(HttpServletRequest request, String cookieName) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if (cookieName.equals(cookie.getName())) { + return Optional.of(cookie.getValue()); + } + } + } + return Optional.empty(); + } + + public void addJwtTokenToCookie(String Jwttoken, HttpServletResponse response) { + // Create a new cookie with the JWT token + Cookie cookie = new Cookie("Jwttoken", Jwttoken); + cookie.setHttpOnly(true); // Prevent JavaScript access for security + cookie.setSecure(true); // Ensure the cookie is sent only over HTTPS + cookie.setMaxAge(60 * 60 * 24); // 1 day expiration time + cookie.setPath("/"); // Make the cookie available for the entire application + response.addCookie(cookie); // Add the cookie to the response + } + + public String getJwtTokenFromCookie(HttpServletRequest request) { + return Arrays.stream(request.getCookies()).filter(cookie -> "Jwttoken".equals(cookie.getName())) + .map(Cookie::getValue).findFirst().orElse(null); + } } - diff --git a/src/main/java/com/iemr/common/utils/FilterConfig.java b/src/main/java/com/iemr/common/utils/FilterConfig.java index c9617362..1f15a7fa 100644 --- a/src/main/java/com/iemr/common/utils/FilterConfig.java +++ b/src/main/java/com/iemr/common/utils/FilterConfig.java @@ -6,13 +6,14 @@ @Configuration public class FilterConfig { - + @Bean - public FilterRegistrationBean jwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil) { - FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); - registrationBean.setFilter(new JwtUserIdValidationFilter(jwtAuthenticationUtil)); - registrationBean.addUrlPatterns("/*"); // Apply filter to all API endpoints - return registrationBean; - } + public FilterRegistrationBean jwtUserIdValidationFilter( + JwtAuthenticationUtil jwtAuthenticationUtil) { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new JwtUserIdValidationFilter(jwtAuthenticationUtil)); + registrationBean.addUrlPatterns("/*"); // Apply filter to all API endpoints + return registrationBean; + } } diff --git a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java index 41591745..437e9637 100644 --- a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java @@ -19,73 +19,74 @@ @Component public class JwtAuthenticationUtil { - @Autowired - private final CookieUtil cookieUtil; - @Autowired - private final JwtUtil jwtUtil; - private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - @Autowired - private IEMRAdminUserServiceImpl iEMRAdminUserServiceImpl; - - public JwtAuthenticationUtil(CookieUtil cookieUtil, JwtUtil jwtUtil) { - this.cookieUtil = cookieUtil; - this.jwtUtil = jwtUtil; - } - - public ResponseEntity validateJwtToken(HttpServletRequest request) { - Optional jwtTokenOpt = cookieUtil.getCookieValue(request, "Jwttoken"); - - if (jwtTokenOpt.isEmpty()) { - return ResponseEntity.status(HttpStatus.UNAUTHORIZED) - .body("Error 401: Unauthorized - JWT Token is not set!"); - } - - String jwtToken = jwtTokenOpt.get(); - - // Validate the token - Claims claims = jwtUtil.validateToken(jwtToken); - if (claims == null) { - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Error 401: Unauthorized - Invalid JWT Token!"); - } - - // Extract username from token - String usernameFromToken = claims.getSubject(); - if (usernameFromToken == null || usernameFromToken.isEmpty()) { - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Error 401: Unauthorized - Username is missing!"); - } - - // Return the username if valid - return ResponseEntity.ok(usernameFromToken); - } - - public boolean validateUserIdAndJwtToken(String jwtToken) throws IEMRException { - try { - // Validate JWT token and extract claims - Claims claims = jwtUtil.validateToken(jwtToken); - - if (claims == null) { - throw new IEMRException("Invalid JWT token."); - } - - String userId = claims.get("userId", String.class); - String tokenUsername = jwtUtil.extractUsername(jwtToken); - - // Fetch user based on userId from the database or cache - User user = iEMRAdminUserServiceImpl.getUserById(Long.parseLong(userId)); - if (user == null) { - throw new IEMRException("Invalid User ID."); - } - - // Check if the token's username matches the user retrieved by userId - if (!user.getUserName().equalsIgnoreCase(tokenUsername)) { - throw new IEMRException("JWT token and User ID mismatch."); - } - - return true; // Valid userId and JWT token - } catch (Exception e) { - logger.error("Validation failed: " + e.getMessage(), e); - throw new IEMRException("Validation error: " + e.getMessage(), e); - } - } + @Autowired + private final CookieUtil cookieUtil; + @Autowired + private final JwtUtil jwtUtil; + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + @Autowired + private IEMRAdminUserServiceImpl iEMRAdminUserServiceImpl; + + public JwtAuthenticationUtil(CookieUtil cookieUtil, JwtUtil jwtUtil) { + this.cookieUtil = cookieUtil; + this.jwtUtil = jwtUtil; + } + + public ResponseEntity validateJwtToken(HttpServletRequest request) { + Optional jwtTokenOpt = cookieUtil.getCookieValue(request, "Jwttoken"); + + if (jwtTokenOpt.isEmpty()) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body("Error 401: Unauthorized - JWT Token is not set!"); + } + + String jwtToken = jwtTokenOpt.get(); + + // Validate the token + Claims claims = jwtUtil.validateToken(jwtToken); + if (claims == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Error 401: Unauthorized - Invalid JWT Token!"); + } + + // Extract username from token + String usernameFromToken = claims.getSubject(); + if (usernameFromToken == null || usernameFromToken.isEmpty()) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED) + .body("Error 401: Unauthorized - Username is missing!"); + } + + // Return the username if valid + return ResponseEntity.ok(usernameFromToken); + } + + public boolean validateUserIdAndJwtToken(String jwtToken) throws IEMRException { + try { + // Validate JWT token and extract claims + Claims claims = jwtUtil.validateToken(jwtToken); + + if (claims == null) { + throw new IEMRException("Invalid JWT token."); + } + + String userId = claims.get("userId", String.class); + String tokenUsername = jwtUtil.extractUsername(jwtToken); + + // Fetch user based on userId from the database or cache + User user = iEMRAdminUserServiceImpl.getUserById(Long.parseLong(userId)); + if (user == null) { + throw new IEMRException("Invalid User ID."); + } + + // Check if the token's username matches the user retrieved by userId + if (!user.getUserName().equalsIgnoreCase(tokenUsername)) { + throw new IEMRException("JWT token and User ID mismatch."); + } + + return true; // Valid userId and JWT token + } catch (Exception e) { + logger.error("Validation failed: " + e.getMessage(), e); + throw new IEMRException("Validation error: " + e.getMessage(), e); + } + } } diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index b1905b2c..47f1f1b1 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -18,93 +18,92 @@ @Component public class JwtUserIdValidationFilter implements Filter { - private final JwtAuthenticationUtil jwtAuthenticationUtil; - private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); - - public JwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil) { - this.jwtAuthenticationUtil = jwtAuthenticationUtil; - } - - @Override - public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) - throws IOException, ServletException { - HttpServletRequest request = (HttpServletRequest) servletRequest; - HttpServletResponse response = (HttpServletResponse) servletResponse; - - String path = request.getRequestURI(); - String contextPath = request.getContextPath(); - logger.info("JwtUserIdValidationFilter invoked for path: " + path); - - // Log cookies for debugging - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (Cookie cookie : cookies) { - if ("userId".equals(cookie.getName())) { - logger.warn("userId found in cookies! Clearing it..."); - clearUserIdCookie(response); // Explicitly remove userId cookie - } - } - } else { - logger.info("No cookies found in the request"); - } - - - // Log headers for debugging - String jwtTokenFromHeader = request.getHeader("Jwttoken"); - logger.info("JWT token from header: " + jwtTokenFromHeader); - - // Skip login and public endpoints - if (path.equals(contextPath + "/user/userAuthenticate") || - path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") || - path.startsWith(contextPath + "/public")) { - logger.info("Skipping filter for path: " + path); - filterChain.doFilter(servletRequest, servletResponse); - return; - } - - try { - // Retrieve JWT token from cookies - String jwtTokenFromCookie = getJwtTokenFromCookies(request); - logger.info("JWT token from cookie: " + jwtTokenFromCookie); - - // Determine which token (cookie or header) to validate - String jwtToken = jwtTokenFromCookie != null ? jwtTokenFromCookie : jwtTokenFromHeader; - if (jwtToken == null) { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "JWT token not found in cookies or headers"); - return; - } - - // Validate JWT token and userId - boolean isValid = jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtToken); - - if (isValid) { - // If token is valid, allow the request to proceed - filterChain.doFilter(servletRequest, servletResponse); - } else { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid JWT token"); - } - } catch (Exception e) { - logger.error("Authorization error: ", e); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authorization error: " + e.getMessage()); - } - } - - private String getJwtTokenFromCookies(HttpServletRequest request) { - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (Cookie cookie : cookies) { - if (cookie.getName().equals("Jwttoken")) { - return cookie.getValue(); - } - } - } - return null; - } - - private void clearUserIdCookie(HttpServletResponse response) { - Cookie cookie = new Cookie("userId", null); - cookie.setPath("/"); - cookie.setMaxAge(0); // Invalidate the cookie - response.addCookie(cookie); - } + private final JwtAuthenticationUtil jwtAuthenticationUtil; + private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); + + public JwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil) { + this.jwtAuthenticationUtil = jwtAuthenticationUtil; + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + + String path = request.getRequestURI(); + String contextPath = request.getContextPath(); + logger.info("JwtUserIdValidationFilter invoked for path: " + path); + + // Log cookies for debugging + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if ("userId".equals(cookie.getName())) { + logger.warn("userId found in cookies! Clearing it..."); + clearUserIdCookie(response); // Explicitly remove userId cookie + } + } + } else { + logger.info("No cookies found in the request"); + } + + // Log headers for debugging + String jwtTokenFromHeader = request.getHeader("Jwttoken"); + logger.info("JWT token from header: " + jwtTokenFromHeader); + + // Skip login and public endpoints + if (path.equals(contextPath + "/user/userAuthenticate") + || path.equalsIgnoreCase(contextPath + "/user/logOutUserFromConcurrentSession") + || path.startsWith(contextPath + "/public")) { + logger.info("Skipping filter for path: " + path); + filterChain.doFilter(servletRequest, servletResponse); + return; + } + + try { + // Retrieve JWT token from cookies + String jwtTokenFromCookie = getJwtTokenFromCookies(request); + logger.info("JWT token from cookie: " + jwtTokenFromCookie); + + // Determine which token (cookie or header) to validate + String jwtToken = jwtTokenFromCookie != null ? jwtTokenFromCookie : jwtTokenFromHeader; + if (jwtToken == null) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "JWT token not found in cookies or headers"); + return; + } + + // Validate JWT token and userId + boolean isValid = jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtToken); + + if (isValid) { + // If token is valid, allow the request to proceed + filterChain.doFilter(servletRequest, servletResponse); + } else { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid JWT token"); + } + } catch (Exception e) { + logger.error("Authorization error: ", e); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authorization error: " + e.getMessage()); + } + } + + private String getJwtTokenFromCookies(HttpServletRequest request) { + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if (cookie.getName().equals("Jwttoken")) { + return cookie.getValue(); + } + } + } + return null; + } + + private void clearUserIdCookie(HttpServletResponse response) { + Cookie cookie = new Cookie("userId", null); + cookie.setPath("/"); + cookie.setMaxAge(0); // Invalidate the cookie + response.addCookie(cookie); + } } diff --git a/src/main/java/com/iemr/common/utils/JwtUtil.java b/src/main/java/com/iemr/common/utils/JwtUtil.java index 77a7fa2e..57946532 100644 --- a/src/main/java/com/iemr/common/utils/JwtUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtUtil.java @@ -4,8 +4,6 @@ import java.util.Date; import java.util.function.Function; -import javax.crypto.spec.SecretKeySpec; - import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -16,63 +14,55 @@ @Component public class JwtUtil { - + @Value("${jwt.secret}") - private String SECRET_KEY; + private String SECRET_KEY; private static final long EXPIRATION_TIME = 24 * 60 * 60 * 1000; // 1 day in milliseconds // Generate a key using the secret - private Key getSigningKey() { - if (SECRET_KEY == null || SECRET_KEY.isEmpty()) { - throw new IllegalStateException("JWT secret key is not set in application.properties"); - } - return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); - } + private Key getSigningKey() { + if (SECRET_KEY == null || SECRET_KEY.isEmpty()) { + throw new IllegalStateException("JWT secret key is not set in application.properties"); + } + return Keys.hmacShaKeyFor(SECRET_KEY.getBytes()); + } // Generate JWT Token public String generateToken(String username, String userId) { - Date now = new Date(); - Date expiryDate = new Date(now.getTime() + EXPIRATION_TIME); + Date now = new Date(); + Date expiryDate = new Date(now.getTime() + EXPIRATION_TIME); - // Include the userId in the JWT claims - return Jwts.builder() - .setSubject(username) - .claim("userId", userId) // Add userId as a claim - .setIssuedAt(now) - .setExpiration(expiryDate) - .signWith(getSigningKey(), SignatureAlgorithm.HS256) - .compact(); + // Include the userId in the JWT claims + return Jwts.builder().setSubject(username).claim("userId", userId) // Add userId as a claim + .setIssuedAt(now).setExpiration(expiryDate).signWith(getSigningKey(), SignatureAlgorithm.HS256) + .compact(); } - // Validate and parse JWT Token public Claims validateToken(String token) { - try { - return Jwts.parserBuilder() - .setSigningKey(getSigningKey()) - .build() - .parseClaimsJws(token) - .getBody(); - } catch (Exception e) { - return null; // Handle token parsing/validation errors - } - } + try { + // Use the JwtParserBuilder correctly in version 0.12.6 + return Jwts.parser() // Correct method in 0.12.6 to get JwtParserBuilder + .setSigningKey(getSigningKey()) // Set the signing key + .build() // Build the JwtParser + .parseClaimsJws(token) // Parse and validate the token + .getBody(); + } catch (Exception e) { + return null; // Handle token parsing/validation errors + } + } - public String extractUsername(String token) { - return extractClaim(token, Claims::getSubject); - } + public String extractUsername(String token) { + return extractClaim(token, Claims::getSubject); + } - public T extractClaim(String token, Function claimsResolver) { - final Claims claims = extractAllClaims(token); - return claimsResolver.apply(claims); - } + public T extractClaim(String token, Function claimsResolver) { + final Claims claims = extractAllClaims(token); + return claimsResolver.apply(claims); + } - private Claims extractAllClaims(String token) { - return Jwts.parserBuilder() - .setSigningKey(getSigningKey()) - .build() - .parseClaimsJws(token) - .getBody(); - } + private Claims extractAllClaims(String token) { + return Jwts.parser().setSigningKey(getSigningKey()).build().parseClaimsJws(token).getBody(); + } } \ No newline at end of file From b2452fff96953f7702075b33ec8bc05258d5c817 Mon Sep 17 00:00:00 2001 From: IN40068837 Date: Tue, 10 Dec 2024 16:06:24 +0530 Subject: [PATCH 04/11] corrected by coderabbit comment --- src/main/environment/common_ci.properties | 2 +- src/main/environment/common_dev.properties | 2 +- src/main/environment/common_example.properties | 2 +- src/main/environment/common_test.properties | 2 +- src/main/environment/common_uat.properties | 2 +- .../java/com/iemr/common/utils/JwtAuthenticationUtil.java | 4 ++-- .../java/com/iemr/common/utils/JwtUserIdValidationFilter.java | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 5485e928..9948b198 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -139,4 +139,4 @@ eAusadhaUrl=https://dlc.kar.nic.in/e-services/api/DWInstituteInward eausadhaAuthorization= spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true -jwt.secret= +jwt.secret=@JWT_SECRET_KEY@ diff --git a/src/main/environment/common_dev.properties b/src/main/environment/common_dev.properties index 85c191f5..a1bde433 100644 --- a/src/main/environment/common_dev.properties +++ b/src/main/environment/common_dev.properties @@ -165,5 +165,5 @@ spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true fileBasePath =/Doc -jwt.secret= +jwt.secret=@JWT_SECRET_KEY@ diff --git a/src/main/environment/common_example.properties b/src/main/environment/common_example.properties index 21a353fe..1e39f9d1 100644 --- a/src/main/environment/common_example.properties +++ b/src/main/environment/common_example.properties @@ -109,5 +109,5 @@ eAusadhaUrl=https://dlc.kar.nic.in/e-services/api/DWInstituteInward eausadhaAuthorization= spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true -jwt.secret= +jwt.secret=@JWT_SECRET_KEY@ diff --git a/src/main/environment/common_test.properties b/src/main/environment/common_test.properties index 31c0c1d4..b0e4c1fc 100644 --- a/src/main/environment/common_test.properties +++ b/src/main/environment/common_test.properties @@ -166,5 +166,5 @@ spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true fileBasePath =/Doc -jwt.secret= +jwt.secret=@JWT_SECRET_KEY@ diff --git a/src/main/environment/common_uat.properties b/src/main/environment/common_uat.properties index 8f1e0965..2265b293 100644 --- a/src/main/environment/common_uat.properties +++ b/src/main/environment/common_uat.properties @@ -138,4 +138,4 @@ spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true fileBasePath =/Doc -jwt.secret= +jwt.secret=@JWT_SECRET_KEY@ diff --git a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java index 437e9637..e57a0755 100644 --- a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java @@ -20,9 +20,9 @@ public class JwtAuthenticationUtil { @Autowired - private final CookieUtil cookieUtil; + private CookieUtil cookieUtil; @Autowired - private final JwtUtil jwtUtil; + private JwtUtil jwtUtil; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Autowired diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 47f1f1b1..5837ec7b 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -50,7 +50,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo // Log headers for debugging String jwtTokenFromHeader = request.getHeader("Jwttoken"); - logger.info("JWT token from header: " + jwtTokenFromHeader); + logger.info("JWT token from header: "); // Skip login and public endpoints if (path.equals(contextPath + "/user/userAuthenticate") @@ -64,7 +64,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo try { // Retrieve JWT token from cookies String jwtTokenFromCookie = getJwtTokenFromCookies(request); - logger.info("JWT token from cookie: " + jwtTokenFromCookie); + logger.info("JWT token from cookie: "); // Determine which token (cookie or header) to validate String jwtToken = jwtTokenFromCookie != null ? jwtTokenFromCookie : jwtTokenFromHeader; From 1323c41059af4729277ae4c0acb13af1fa993346 Mon Sep 17 00:00:00 2001 From: IN40068837 Date: Fri, 13 Dec 2024 12:28:34 +0530 Subject: [PATCH 05/11] sonarqube analysis code change --- .../java/com/iemr/common/utils/JwtUserIdValidationFilter.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java index 5837ec7b..0c12c3a6 100644 --- a/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java +++ b/src/main/java/com/iemr/common/utils/JwtUserIdValidationFilter.java @@ -103,6 +103,8 @@ private String getJwtTokenFromCookies(HttpServletRequest request) { private void clearUserIdCookie(HttpServletResponse response) { Cookie cookie = new Cookie("userId", null); cookie.setPath("/"); + cookie.setHttpOnly(true); + cookie.setSecure(true); cookie.setMaxAge(0); // Invalidate the cookie response.addCookie(cookie); } From b760ebc6397bd35f8f5057d7ec9e715aab6908ad Mon Sep 17 00:00:00 2001 From: IN40068837 Date: Fri, 13 Dec 2024 12:47:39 +0530 Subject: [PATCH 06/11] sonarqube analysis --- src/main/java/com/iemr/common/utils/JwtUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/iemr/common/utils/JwtUtil.java b/src/main/java/com/iemr/common/utils/JwtUtil.java index 57946532..a6e8b942 100644 --- a/src/main/java/com/iemr/common/utils/JwtUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtUtil.java @@ -18,7 +18,7 @@ public class JwtUtil { @Value("${jwt.secret}") private String SECRET_KEY; - private static final long EXPIRATION_TIME = 24 * 60 * 60 * 1000; // 1 day in milliseconds + private static final long EXPIRATION_TIME = 24L * 60 * 60 * 1000; // 1 day in milliseconds // Generate a key using the secret private Key getSigningKey() { From a31cbe6888f7760487a898d6d78152ebd8c980d9 Mon Sep 17 00:00:00 2001 From: IN40068837 Date: Fri, 13 Dec 2024 19:50:08 +0530 Subject: [PATCH 07/11] fixed issues --- src/main/environment/common_ci.properties | 2 +- src/main/environment/common_dev.properties | 3 +-- src/main/environment/common_example.properties | 3 +-- src/main/environment/common_test.properties | 2 +- src/main/environment/common_uat.properties | 2 +- .../java/com/iemr/common/utils/JwtAuthenticationUtil.java | 6 ------ 6 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/main/environment/common_ci.properties b/src/main/environment/common_ci.properties index 9948b198..557e4bb1 100644 --- a/src/main/environment/common_ci.properties +++ b/src/main/environment/common_ci.properties @@ -139,4 +139,4 @@ eAusadhaUrl=https://dlc.kar.nic.in/e-services/api/DWInstituteInward eausadhaAuthorization= spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true -jwt.secret=@JWT_SECRET_KEY@ +jwt.secret=@env.JWT_SECRET_KEY@ diff --git a/src/main/environment/common_dev.properties b/src/main/environment/common_dev.properties index a1bde433..f7682d98 100644 --- a/src/main/environment/common_dev.properties +++ b/src/main/environment/common_dev.properties @@ -165,5 +165,4 @@ spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true fileBasePath =/Doc -jwt.secret=@JWT_SECRET_KEY@ - +jwt.secret= diff --git a/src/main/environment/common_example.properties b/src/main/environment/common_example.properties index 1e39f9d1..696d8e47 100644 --- a/src/main/environment/common_example.properties +++ b/src/main/environment/common_example.properties @@ -109,5 +109,4 @@ eAusadhaUrl=https://dlc.kar.nic.in/e-services/api/DWInstituteInward eausadhaAuthorization= spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true -jwt.secret=@JWT_SECRET_KEY@ - +jwt.secret= diff --git a/src/main/environment/common_test.properties b/src/main/environment/common_test.properties index b0e4c1fc..3ec80088 100644 --- a/src/main/environment/common_test.properties +++ b/src/main/environment/common_test.properties @@ -166,5 +166,5 @@ spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true fileBasePath =/Doc -jwt.secret=@JWT_SECRET_KEY@ +jwt.secret= diff --git a/src/main/environment/common_uat.properties b/src/main/environment/common_uat.properties index 2265b293..bc346b33 100644 --- a/src/main/environment/common_uat.properties +++ b/src/main/environment/common_uat.properties @@ -138,4 +138,4 @@ spring.main.allow-bean-definition-overriding=true spring.main.allow-circular-references=true fileBasePath =/Doc -jwt.secret=@JWT_SECRET_KEY@ +jwt.secret= diff --git a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java index e57a0755..1f8b30dd 100644 --- a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java @@ -70,7 +70,6 @@ public boolean validateUserIdAndJwtToken(String jwtToken) throws IEMRException { } String userId = claims.get("userId", String.class); - String tokenUsername = jwtUtil.extractUsername(jwtToken); // Fetch user based on userId from the database or cache User user = iEMRAdminUserServiceImpl.getUserById(Long.parseLong(userId)); @@ -78,11 +77,6 @@ public boolean validateUserIdAndJwtToken(String jwtToken) throws IEMRException { throw new IEMRException("Invalid User ID."); } - // Check if the token's username matches the user retrieved by userId - if (!user.getUserName().equalsIgnoreCase(tokenUsername)) { - throw new IEMRException("JWT token and User ID mismatch."); - } - return true; // Valid userId and JWT token } catch (Exception e) { logger.error("Validation failed: " + e.getMessage(), e); From 5309ce0f9a30802762b567a5e1a8c054fb3088bb Mon Sep 17 00:00:00 2001 From: IN40068837 Date: Thu, 19 Dec 2024 11:59:17 +0530 Subject: [PATCH 08/11] user fetch from redis concept --- .../com/iemr/common/config/RedisConfig.java | 27 +++++++++-- .../controller/users/IEMRAdminController.java | 13 +++++ .../java/com/iemr/common/data/users/User.java | 4 +- .../common/utils/JwtAuthenticationUtil.java | 48 ++++++++++++++++++- 4 files changed, 85 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/iemr/common/config/RedisConfig.java b/src/main/java/com/iemr/common/config/RedisConfig.java index ae1519e0..3e67e7a3 100644 --- a/src/main/java/com/iemr/common/config/RedisConfig.java +++ b/src/main/java/com/iemr/common/config/RedisConfig.java @@ -23,14 +23,33 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.session.data.redis.config.ConfigureRedisAction; @Configuration public class RedisConfig { - + + @Bean + public ConfigureRedisAction configureRedisAction() { + return ConfigureRedisAction.NO_OP; + } + @Bean - public ConfigureRedisAction configureRedisAction() { - return ConfigureRedisAction.NO_OP; - } + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(factory); + + // Use StringRedisSerializer for keys + template.setKeySerializer(new StringRedisSerializer()); + + // Use Jackson2JsonRedisSerializer for values (objects) + Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class); + template.setValueSerializer(serializer); + + return template; + } } 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 2a5f1ca9..352b0544 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -28,6 +28,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.concurrent.TimeUnit; import javax.ws.rs.core.MediaType; @@ -36,6 +37,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; @@ -93,6 +95,8 @@ public class IEMRAdminController { private CookieUtil cookieUtil; @Autowired private JwtAuthenticationUtil jwtAuthenticationUtil; + @Autowired + private RedisTemplate redisTemplate; private AESUtil aesUtil; @@ -162,6 +166,15 @@ public String userAuthenticate( if (mUser.size() == 1) { String Jwttoken = jwtUtil.generateToken(m_User.getUserName(), mUser.get(0).getUserID().toString()); logger.info("jwt token is:" + Jwttoken); + + User user = new User(); // Assuming the Users class exists + user.setUserID(mUser.get(0).getUserID()); + user.setUserName(mUser.get(0).getUserName()); + + String redisKey = "user_" + mUser.get(0).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); // Set Jwttoken in the response cookie cookieUtil.addJwtTokenToCookie(Jwttoken, httpResponse); diff --git a/src/main/java/com/iemr/common/data/users/User.java b/src/main/java/com/iemr/common/data/users/User.java index d4030347..4fec6aa2 100644 --- a/src/main/java/com/iemr/common/data/users/User.java +++ b/src/main/java/com/iemr/common/data/users/User.java @@ -21,6 +21,7 @@ */ package com.iemr.common.data.users; +import java.io.Serializable; import java.sql.Timestamp; import java.util.List; import java.util.Set; @@ -52,7 +53,7 @@ @Entity @Table(name = "m_user") @Data -public class User { +public class User implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Expose @@ -194,6 +195,7 @@ public class User { private String newPassword = null; @Transient + @JsonIgnore private OutputMapper outPutMapper = new OutputMapper(); // new field for rate-limit, failed authentication diff --git a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java index 1f8b30dd..aad48803 100644 --- a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java @@ -1,15 +1,18 @@ package com.iemr.common.utils; import java.util.Optional; +import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import com.iemr.common.data.users.User; +import com.iemr.common.repository.users.IEMRUserRepositoryCustom; import com.iemr.common.service.users.IEMRAdminUserServiceImpl; import com.iemr.common.utils.exception.IEMRException; @@ -23,6 +26,10 @@ public class JwtAuthenticationUtil { private CookieUtil cookieUtil; @Autowired private JwtUtil jwtUtil; + @Autowired + private RedisTemplate redisTemplate; + @Autowired + private IEMRUserRepositoryCustom iEMRUserRepositoryCustom; private final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); @Autowired @@ -71,8 +78,12 @@ public boolean validateUserIdAndJwtToken(String jwtToken) throws IEMRException { String userId = claims.get("userId", String.class); - // Fetch user based on userId from the database or cache - User user = iEMRAdminUserServiceImpl.getUserById(Long.parseLong(userId)); + // Check if user data is present in Redis + User user = getUserFromCache(userId); + if (user == null) { + // If not in Redis, fetch from DB and cache the result + user = fetchUserFromDB(userId); + } if (user == null) { throw new IEMRException("Invalid User ID."); } @@ -83,4 +94,37 @@ public boolean validateUserIdAndJwtToken(String jwtToken) throws IEMRException { throw new IEMRException("Validation error: " + e.getMessage(), e); } } + + private User getUserFromCache(String userId) { + String redisKey = "user_" + userId; // The Redis key format + User user = (User) redisTemplate.opsForValue().get(redisKey); + + if (user == null) { + logger.warn("User not found in Redis. Will try to fetch from DB."); + } else { + logger.info("User fetched successfully from Redis."); + } + + return user; // Returns null if not found + } + + private User fetchUserFromDB(String userId) { + // This method will only be called if the user is not found in Redis. + String redisKey = "user_" + userId; // Redis key format + + // Fetch user from DB + User user = iEMRUserRepositoryCustom.findByUserID(Long.parseLong(userId)); + + if (user != null) { + // Cache the user in Redis for future requests (cache for 30 minutes) + redisTemplate.opsForValue().set(redisKey, user, 30, TimeUnit.MINUTES); + + // Log that the user has been stored in Redis + logger.info("User stored in Redis with key: " + redisKey); + } else { + logger.warn("User not found for userId: " + userId); + } + + return user; + } } From 016785e1665ea950dd6e46c0e49dc9be5b169dfa Mon Sep 17 00:00:00 2001 From: IN40068837 Date: Fri, 20 Dec 2024 13:55:38 +0530 Subject: [PATCH 09/11] user fetching concept modified --- .../com/iemr/common/CommonApplication.java | 31 +++++++++++++++---- .../com/iemr/common/config/RedisConfig.java | 12 ++++--- .../controller/users/IEMRAdminController.java | 2 -- .../java/com/iemr/common/data/users/User.java | 1 + 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/iemr/common/CommonApplication.java b/src/main/java/com/iemr/common/CommonApplication.java index b1e03d41..83078018 100644 --- a/src/main/java/com/iemr/common/CommonApplication.java +++ b/src/main/java/com/iemr/common/CommonApplication.java @@ -22,14 +22,18 @@ package com.iemr.common; import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.web.client.RestTemplate; +import com.iemr.common.data.users.User; import com.iemr.common.utils.IEMRApplBeans; @SpringBootApplication @@ -41,11 +45,11 @@ public IEMRApplBeans instantiateBeans() { return new IEMRApplBeans(); } - @Bean - public RestTemplate restTemplate() { - return new RestTemplate(); - } - + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } + public static void main(String[] args) { SpringApplication.run(CommonApplication.class, args); } @@ -54,4 +58,19 @@ protected SpringApplicationBuilder configure(SpringApplicationBuilder applicatio return application.sources(new Class[] { CommonApplication.class }); } + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + RedisTemplate template = new RedisTemplate<>(); + template.setConnectionFactory(factory); + + // Use StringRedisSerializer for keys (userId) + template.setKeySerializer(new StringRedisSerializer()); + + // Use Jackson2JsonRedisSerializer for values (Users objects) + Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(User.class); + template.setValueSerializer(serializer); + + return template; + } + } diff --git a/src/main/java/com/iemr/common/config/RedisConfig.java b/src/main/java/com/iemr/common/config/RedisConfig.java index 3e67e7a3..faac71ae 100644 --- a/src/main/java/com/iemr/common/config/RedisConfig.java +++ b/src/main/java/com/iemr/common/config/RedisConfig.java @@ -29,6 +29,8 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.session.data.redis.config.ConfigureRedisAction; +import com.iemr.common.data.users.User; + @Configuration public class RedisConfig { @@ -38,15 +40,15 @@ public ConfigureRedisAction configureRedisAction() { } @Bean - public RedisTemplate redisTemplate(RedisConnectionFactory factory) { - RedisTemplate template = new RedisTemplate<>(); + public RedisTemplate redisTemplate(RedisConnectionFactory factory) { + RedisTemplate template = new RedisTemplate<>(); template.setConnectionFactory(factory); - // Use StringRedisSerializer for keys + // Use StringRedisSerializer for keys (userId) template.setKeySerializer(new StringRedisSerializer()); - // Use Jackson2JsonRedisSerializer for values (objects) - Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(Object.class); + // Use Jackson2JsonRedisSerializer for values (Users objects) + Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer<>(User.class); template.setValueSerializer(serializer); return template; 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 352b0544..b5f0dca6 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -179,8 +179,6 @@ public String userAuthenticate( // Set Jwttoken in the response cookie cookieUtil.addJwtTokenToCookie(Jwttoken, httpResponse); - resMap.put("Jwttoken", Jwttoken); - logger.info("response coming from jwt:" + resMap); createUserMapping(mUser.get(0), resMap, serviceRoleMultiMap, serviceRoleMap, serviceRoleList, previlegeObj); } else { diff --git a/src/main/java/com/iemr/common/data/users/User.java b/src/main/java/com/iemr/common/data/users/User.java index 4fec6aa2..4710b11d 100644 --- a/src/main/java/com/iemr/common/data/users/User.java +++ b/src/main/java/com/iemr/common/data/users/User.java @@ -27,6 +27,7 @@ import java.util.Set; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.google.gson.annotations.Expose; import com.iemr.common.data.callhandling.OutboundCallRequest; import com.iemr.common.data.feedback.FeedbackDetails; From 489f5cd580d88f1082f2037d5b78c503f532dadb Mon Sep 17 00:00:00 2001 From: IN40068837 Date: Tue, 24 Dec 2024 13:53:42 +0530 Subject: [PATCH 10/11] user fetch concept modify --- .../com/iemr/common/utils/CookieUtil.java | 1 - .../common/utils/JwtAuthenticationUtil.java | 28 +++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/iemr/common/utils/CookieUtil.java b/src/main/java/com/iemr/common/utils/CookieUtil.java index e777e6c4..e27bc147 100644 --- a/src/main/java/com/iemr/common/utils/CookieUtil.java +++ b/src/main/java/com/iemr/common/utils/CookieUtil.java @@ -28,7 +28,6 @@ public void addJwtTokenToCookie(String Jwttoken, HttpServletResponse response) { // Create a new cookie with the JWT token Cookie cookie = new Cookie("Jwttoken", Jwttoken); cookie.setHttpOnly(true); // Prevent JavaScript access for security - cookie.setSecure(true); // Ensure the cookie is sent only over HTTPS cookie.setMaxAge(60 * 60 * 24); // 1 day expiration time cookie.setPath("/"); // Make the cookie available for the entire application response.addCookie(cookie); // Add the cookie to the response diff --git a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java index aad48803..c9e27459 100644 --- a/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java +++ b/src/main/java/com/iemr/common/utils/JwtAuthenticationUtil.java @@ -107,24 +107,24 @@ private User getUserFromCache(String userId) { return user; // Returns null if not found } - + private User fetchUserFromDB(String userId) { - // This method will only be called if the user is not found in Redis. - String redisKey = "user_" + userId; // Redis key format + // This method will only be called if the user is not found in Redis. + String redisKey = "user_" + userId; // Redis key format - // Fetch user from DB - User user = iEMRUserRepositoryCustom.findByUserID(Long.parseLong(userId)); + // Fetch user from DB + User user = iEMRUserRepositoryCustom.findByUserID(Long.parseLong(userId)); - if (user != null) { - // Cache the user in Redis for future requests (cache for 30 minutes) - redisTemplate.opsForValue().set(redisKey, user, 30, TimeUnit.MINUTES); + if (user != null) { + // Cache the user in Redis for future requests (cache for 30 minutes) + redisTemplate.opsForValue().set(redisKey, user, 30, TimeUnit.MINUTES); - // Log that the user has been stored in Redis - logger.info("User stored in Redis with key: " + redisKey); - } else { - logger.warn("User not found for userId: " + userId); - } + // Log that the user has been stored in Redis + logger.info("User stored in Redis with key: " + redisKey); + } else { + logger.warn("User not found for userId: " + userId); + } - return user; + return user; } } From 300d192dcfdb073d0439ca11af4b62527a7aa530 Mon Sep 17 00:00:00 2001 From: IN40068837 Date: Tue, 24 Dec 2024 15:45:33 +0530 Subject: [PATCH 11/11] sonar qube issue --- .../iemr/common/controller/users/IEMRAdminController.java | 2 +- src/main/java/com/iemr/common/utils/CookieUtil.java | 5 ++++- 2 files changed, 5 insertions(+), 2 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 b5f0dca6..0c0aaac7 100644 --- a/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java +++ b/src/main/java/com/iemr/common/controller/users/IEMRAdminController.java @@ -177,7 +177,7 @@ public String userAuthenticate( redisTemplate.opsForValue().set(redisKey, user, 30, TimeUnit.MINUTES); // Set Jwttoken in the response cookie - cookieUtil.addJwtTokenToCookie(Jwttoken, httpResponse); + cookieUtil.addJwtTokenToCookie(Jwttoken, httpResponse, request); createUserMapping(mUser.get(0), resMap, serviceRoleMultiMap, serviceRoleMap, serviceRoleList, previlegeObj); diff --git a/src/main/java/com/iemr/common/utils/CookieUtil.java b/src/main/java/com/iemr/common/utils/CookieUtil.java index e27bc147..7fb103f5 100644 --- a/src/main/java/com/iemr/common/utils/CookieUtil.java +++ b/src/main/java/com/iemr/common/utils/CookieUtil.java @@ -24,12 +24,15 @@ public Optional getCookieValue(HttpServletRequest request, String cookie return Optional.empty(); } - public void addJwtTokenToCookie(String Jwttoken, HttpServletResponse response) { + public void addJwtTokenToCookie(String Jwttoken, HttpServletResponse response, HttpServletRequest request) { // Create a new cookie with the JWT token Cookie cookie = new Cookie("Jwttoken", Jwttoken); cookie.setHttpOnly(true); // Prevent JavaScript access for security cookie.setMaxAge(60 * 60 * 24); // 1 day expiration time cookie.setPath("/"); // Make the cookie available for the entire application + if ("https".equalsIgnoreCase(request.getScheme())) { + cookie.setSecure(true); // Secure flag only on HTTPS + } response.addCookie(cookie); // Add the cookie to the response }