Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,32 +67,47 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
}

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;
}
String jwtFromCookie = getJwtTokenFromCookies(request);
String jwtFromHeader = request.getHeader("JwtToken");
String authHeader = request.getHeader("Authorization");

if (jwtFromCookie != null) {
logger.info("Validating JWT token from cookie");
if (jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtFromCookie)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}

if (jwtFromHeader != null) {
logger.info("Validating JWT token from header");
if (jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtFromHeader)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}
Comment on lines +70 to +88
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

πŸ› οΈ Refactor suggestion

⚠️ Potential issue

Header name mismatch silently breaks authentication

You first read "Jwttoken" (line 54) and later read "JwtToken" (line 71).
Many servlet containers treat headers as case-insensitive but the spelling must still match on the client side. If clients send "Jwttoken" (as before), the second read will return null, causing the header path to be skipped and – depending on the user-agent – the request may be granted without validation.

-String jwtFromHeader = request.getHeader("JwtToken");
+// Use a single, canonical header name through the whole filter
+final String JWT_HEADER = "Jwttoken";
+String jwtFromHeader = request.getHeader(JWT_HEADER);

Also consider turning the cookie/header names into private static final constants to prevent this kind of drift.

πŸ“ Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
String jwtFromCookie = getJwtTokenFromCookies(request);
String jwtFromHeader = request.getHeader("JwtToken");
String authHeader = request.getHeader("Authorization");
if (jwtFromCookie != null) {
logger.info("Validating JWT token from cookie");
if (jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtFromCookie)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}
if (jwtFromHeader != null) {
logger.info("Validating JWT token from header");
if (jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtFromHeader)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}
String jwtFromCookie = getJwtTokenFromCookies(request);
// Use a single, canonical header name through the whole filter
final String JWT_HEADER = "Jwttoken";
String jwtFromHeader = request.getHeader(JWT_HEADER);
String authHeader = request.getHeader("Authorization");
if (jwtFromCookie != null) {
logger.info("Validating JWT token from cookie");
if (jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtFromCookie)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}
if (jwtFromHeader != null) {
logger.info("Validating JWT token from header");
if (jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtFromHeader)) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}
}
πŸ€– Prompt for AI Agents
In src/main/java/com/iemr/helpline104/utils/JwtUserIdValidationFilter.java
around lines 54 and 70-88, the header name "JwtToken" is inconsistently spelled
as "Jwttoken" and "JwtToken", causing the header read to fail silently and
potentially bypass authentication. To fix this, unify the header name spelling
to a single consistent value used both when reading and in client requests.
Additionally, define the cookie and header names as private static final
constants to avoid such mismatches in the future.

String userAgent = request.getHeader("User-Agent");
logger.info("User-Agent: " + userAgent);

if (userAgent != null && isMobileClient(userAgent) && authHeader != null) {
filterChain.doFilter(servletRequest, servletResponse);
return;
}

logger.warn("No valid authentication token found");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized: Invalid or missing token");

// 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 boolean isMobileClient(String userAgent) {
if (userAgent == null)
return false;
userAgent = userAgent.toLowerCase();
return userAgent.contains("okhttp");
}
private String getJwtTokenFromCookies(HttpServletRequest request) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
Expand Down
Loading