Skip to content

Commit da71080

Browse files
AMM-1456 : JWT validation (#84)
* Skip the JwtToken validation if request coming from mobile * Added condition for Android,ios * CI properties change * Verified acceptance crietaria conditions * Indent and okhttp validated * Handled Authorization in Header * Jwttoken and user-agent validation * null check
1 parent 37a4c5e commit da71080

7 files changed

Lines changed: 148 additions & 33 deletions

File tree

src/main/java/com/wipro/fhir/service/api_channel/APIChannelImpl.java

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.wipro.fhir.data.request_handler.ResourceRequestHandler;
4040
import com.wipro.fhir.data.request_handler.UserAuthAPIResponse;
4141
import com.wipro.fhir.utils.CookieUtil;
42+
import com.wipro.fhir.utils.RestTemplateUtil;
4243
import com.wipro.fhir.utils.exception.FHIRException;
4344
import com.wipro.fhir.utils.mapper.InputMapper;
4445

@@ -72,15 +73,9 @@ public String benSearchByBenID(String Authorization, ResourceRequestHandler reso
7273
String responseBody = null;
7374
if (restTemplate == null)
7475
restTemplate = new RestTemplate();
75-
HttpServletRequest requestHeader = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
76-
.getRequest();
77-
String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader);
78-
79-
MultiValueMap<String, String> header = getHttpHeader(Authorization, "application/json");
80-
HttpEntity<Object> urlRequestOBJ = new HttpEntity<Object>(resourceRequestHandler, header);
81-
header.add("Cookie", "Jwttoken=" + jwtTokenFromCookie);
82-
83-
ResponseEntity<String> response = restTemplate.exchange(benSearchByBenIDURL, HttpMethod.POST, urlRequestOBJ,
76+
77+
HttpEntity<Object> request = RestTemplateUtil.createRequestEntity(resourceRequestHandler, Authorization);
78+
ResponseEntity<String> response = restTemplate.exchange(benSearchByBenIDURL, HttpMethod.POST, request,
8479
String.class);
8580

8681
if (response.getStatusCodeValue() == 200 && response.hasBody()) {
@@ -111,12 +106,8 @@ public String userAuthentication() throws FHIRException {
111106
restTemplate = new RestTemplate();
112107
HttpServletRequest requestHeader = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
113108
.getRequest();
114-
String jwtTokenFromCookie = cookieUtil.getJwtTokenFromCookie(requestHeader);
115-
116-
MultiValueMap<String, String> header = getHttpHeader(null, "application/json");
117-
HttpEntity<Object> urlRequestOBJ = new HttpEntity<Object>(userDetails, header);
118-
header.add("Cookie", "Jwttoken=" + jwtTokenFromCookie);
119-
109+
110+
HttpEntity<Object> urlRequestOBJ = RestTemplateUtil.createRequestEntity(userDetails, requestHeader.getHeader("Authorization"));
120111
ResponseEntity<String> response = restTemplate.exchange(userAuthURL, HttpMethod.POST, urlRequestOBJ,
121112
String.class);
122113

src/main/java/com/wipro/fhir/utils/CookieUtil.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ public Optional<String> getCookieValue(HttpServletRequest request, String cookie
2424
return Optional.empty();
2525
}
2626

27-
public String getJwtTokenFromCookie(HttpServletRequest request) {
27+
public static String getJwtTokenFromCookie(HttpServletRequest request) {
28+
if (request.getCookies() == null) {
29+
return null; // If cookies are null, return null safely.
30+
}
2831
return Arrays.stream(request.getCookies()).filter(cookie -> "Jwttoken".equals(cookie.getName()))
2932
.map(Cookie::getValue).findFirst().orElse(null);
3033
}

src/main/java/com/wipro/fhir/utils/JwtUserIdValidationFilter.java

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import org.slf4j.LoggerFactory;
77
import org.springframework.stereotype.Component;
88

9+
import com.wipro.fhir.utils.http.AuthorizationHeaderRequestWrapper;
10+
911
import jakarta.servlet.Filter;
1012
import jakarta.servlet.FilterChain;
1113
import jakarta.servlet.ServletException;
@@ -29,6 +31,7 @@ public JwtUserIdValidationFilter(JwtAuthenticationUtil jwtAuthenticationUtil) {
2931
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
3032
throws IOException, ServletException {
3133
HttpServletRequest request = (HttpServletRequest) servletRequest;
34+
3235
HttpServletResponse response = (HttpServletResponse) servletResponse;
3336

3437
String path = request.getRequestURI();
@@ -47,11 +50,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
4750
} else {
4851
logger.info("No cookies found in the request");
4952
}
50-
51-
// Log headers for debugging
52-
String jwtTokenFromHeader = request.getHeader("Jwttoken");
53-
logger.info("JWT token from header: ");
54-
53+
5554
// Skip login and public endpoints
5655
if (shouldSkipPath(path, contextPath)) {
5756
filterChain.doFilter(servletRequest, servletResponse);
@@ -66,24 +65,33 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
6665
if (jwtFromCookie != null) {
6766
logger.info("Validating JWT token from cookie");
6867
if (jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtFromCookie)) {
69-
filterChain.doFilter(servletRequest, servletResponse);
68+
69+
AuthorizationHeaderRequestWrapper authorizationHeaderRequestWrapper = new AuthorizationHeaderRequestWrapper(
70+
request, "");
71+
filterChain.doFilter(authorizationHeaderRequestWrapper, servletResponse);
7072
return;
7173
}
72-
}
73-
74-
if (jwtFromHeader != null) {
74+
} else if (jwtFromHeader != null) {
7575
logger.info("Validating JWT token from header");
7676
if (jwtAuthenticationUtil.validateUserIdAndJwtToken(jwtFromHeader)) {
77-
filterChain.doFilter(servletRequest, servletResponse);
77+
AuthorizationHeaderRequestWrapper authorizationHeaderRequestWrapper = new AuthorizationHeaderRequestWrapper(
78+
request, "");
79+
filterChain.doFilter(authorizationHeaderRequestWrapper, servletResponse);
80+
return;
81+
}
82+
} else {
83+
String userAgent = request.getHeader("User-Agent");
84+
logger.info("User-Agent: " + userAgent);
85+
86+
if (userAgent != null && isMobileClient(userAgent) && authHeader != null) {
87+
try {
88+
UserAgentContext.setUserAgent(userAgent);
89+
filterChain.doFilter(servletRequest, servletResponse);
90+
} finally {
91+
UserAgentContext.clear();
92+
}
7893
return;
7994
}
80-
}
81-
String userAgent = request.getHeader("User-Agent");
82-
logger.info("User-Agent: " + userAgent);
83-
84-
if (userAgent != null && isMobileClient(userAgent) && authHeader != null) {
85-
filterChain.doFilter(servletRequest, servletResponse);
86-
return;
8795
}
8896

8997
logger.warn("No valid authentication token found");
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.wipro.fhir.utils;
2+
3+
import org.slf4j.Logger;
4+
import org.slf4j.LoggerFactory;
5+
import org.springframework.http.HttpEntity;
6+
import org.springframework.http.HttpHeaders;
7+
import org.springframework.http.MediaType;
8+
import org.springframework.util.LinkedMultiValueMap;
9+
import org.springframework.util.MultiValueMap;
10+
import org.springframework.web.context.request.RequestContextHolder;
11+
import org.springframework.web.context.request.ServletRequestAttributes;
12+
13+
import jakarta.servlet.http.HttpServletRequest;
14+
15+
public class RestTemplateUtil {
16+
private final static Logger logger = LoggerFactory.getLogger(RestTemplateUtil.class);
17+
18+
public static HttpEntity<Object> createRequestEntity(Object body, String authorization) {
19+
20+
ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
21+
if (servletRequestAttributes == null) {
22+
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
23+
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8");
24+
headers.add(HttpHeaders.AUTHORIZATION, authorization);
25+
return new HttpEntity<>(body, headers);
26+
}
27+
HttpServletRequest requestHeader = servletRequestAttributes.getRequest();
28+
String jwtTokenFromCookie = null;
29+
try {
30+
jwtTokenFromCookie = CookieUtil.getJwtTokenFromCookie(requestHeader);
31+
32+
} catch (Exception e) {
33+
logger.error("Error while getting jwtToken from Cookie" + e.getMessage() );
34+
}
35+
36+
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
37+
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8");
38+
if(null != UserAgentContext.getUserAgent()) {
39+
headers.add(HttpHeaders.USER_AGENT, UserAgentContext.getUserAgent());
40+
}
41+
headers.add(HttpHeaders.AUTHORIZATION, authorization);
42+
headers.add("JwtToken",requestHeader.getHeader("JwtToken"));
43+
if(null != jwtTokenFromCookie) {
44+
headers.add(HttpHeaders.COOKIE, "Jwttoken=" + jwtTokenFromCookie);
45+
}
46+
47+
return new HttpEntity<>(body, headers);
48+
}
49+
50+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.wipro.fhir.utils;
2+
3+
public class UserAgentContext {
4+
private static final ThreadLocal<String> userAgentHolder = new ThreadLocal<>();
5+
6+
public static void setUserAgent(String userAgent) {
7+
userAgentHolder.set(userAgent);
8+
}
9+
10+
public static String getUserAgent() {
11+
return userAgentHolder.get();
12+
}
13+
14+
public static void clear() {
15+
userAgentHolder.remove();
16+
}
17+
18+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.wipro.fhir.utils.http;
2+
3+
4+
import java.util.*;
5+
6+
import jakarta.servlet.http.HttpServletRequest;
7+
import jakarta.servlet.http.HttpServletRequestWrapper;
8+
9+
public class AuthorizationHeaderRequestWrapper extends HttpServletRequestWrapper{
10+
private final String Authorization;
11+
12+
public AuthorizationHeaderRequestWrapper(HttpServletRequest request, String authHeaderValue) {
13+
super(request);
14+
this.Authorization = authHeaderValue;
15+
}
16+
17+
@Override
18+
public String getHeader(String name) {
19+
if ("Authorization".equalsIgnoreCase(name)) {
20+
return Authorization;
21+
}
22+
return super.getHeader(name);
23+
}
24+
25+
@Override
26+
public Enumeration<String> getHeaders(String name) {
27+
if ("Authorization".equalsIgnoreCase(name)) {
28+
return Collections.enumeration(Collections.singletonList(Authorization));
29+
}
30+
return super.getHeaders(name);
31+
}
32+
33+
@Override
34+
public Enumeration<String> getHeaderNames() {
35+
List<String> names = Collections.list(super.getHeaderNames());
36+
if (!names.contains("Authorization")) {
37+
names.add("Authorization");
38+
}
39+
return Collections.enumeration(names);
40+
}
41+
}

src/main/java/com/wipro/fhir/utils/http/HTTPRequestInterceptor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons
5959
boolean status = true;
6060
logger.debug("In preHandle we are Intercepting the Request");
6161
String authorization = request.getHeader("Authorization");
62+
if (authorization == null || authorization.isEmpty()) {
63+
logger.info("Authorization header is null or empty. Skipping HTTPRequestInterceptor.");
64+
return true; // Allow the request to proceed without validation
65+
}
6266
logger.debug("RequestURI::" + request.getRequestURI() + " || Authorization ::" + authorization
6367
+ " || method :: " + request.getMethod());
6468
if (!request.getMethod().equalsIgnoreCase("OPTIONS")) {

0 commit comments

Comments
 (0)