44
55import org .slf4j .Logger ;
66import org .slf4j .LoggerFactory ;
7- import org .springframework .stereotype .Component ;
87
98import com .iemr .ecd .utils .constants .Constants ;
109import com .iemr .ecd .utils .http_request_interceptor .AuthorizationHeaderRequestWrapper ;
1716import jakarta .servlet .http .Cookie ;
1817import jakarta .servlet .http .HttpServletRequest ;
1918import jakarta .servlet .http .HttpServletResponse ;
19+ import java .util .Arrays ;
2020
21- @ Component
2221public class JwtUserIdValidationFilter implements Filter {
2322
2423 private final JwtAuthenticationUtil jwtAuthenticationUtil ;
2524 private final Logger logger = LoggerFactory .getLogger (this .getClass ().getName ());
25+ private final String allowedOrigins ;
2626
27- public JwtUserIdValidationFilter (JwtAuthenticationUtil jwtAuthenticationUtil ) {
27+ public JwtUserIdValidationFilter (JwtAuthenticationUtil jwtAuthenticationUtil ,
28+ String allowedOrigins ) {
2829 this .jwtAuthenticationUtil = jwtAuthenticationUtil ;
30+ this .allowedOrigins = allowedOrigins ;
2931 }
3032
3133 @ Override
@@ -34,6 +36,22 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
3436 HttpServletRequest request = (HttpServletRequest ) servletRequest ;
3537 HttpServletResponse response = (HttpServletResponse ) servletResponse ;
3638
39+ String origin = request .getHeader ("Origin" );
40+ if (origin != null && isOriginAllowed (origin )) {
41+ response .setHeader ("Access-Control-Allow-Origin" , origin );
42+ response .setHeader ("Access-Control-Allow-Methods" , "GET, POST, PUT, DELETE, OPTIONS" );
43+ response .setHeader ("Access-Control-Allow-Headers" , "Authorization, Content-Type, Accept, Jwttoken" );
44+ response .setHeader ("Access-Control-Allow-Credentials" , "true" );
45+ } else {
46+ logger .warn ("Origin [{}] is NOT allowed. CORS headers NOT added." , origin );
47+ }
48+
49+ if ("OPTIONS" .equalsIgnoreCase (request .getMethod ())) {
50+ logger .info ("OPTIONS request - skipping JWT validation" );
51+ response .setStatus (HttpServletResponse .SC_OK );
52+ return ;
53+ }
54+
3755 String path = request .getRequestURI ();
3856 String contextPath = request .getContextPath ();
3957 logger .info ("JwtUserIdValidationFilter invoked for path: " + path );
@@ -103,18 +121,39 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
103121
104122 logger .warn ("No valid authentication token found" );
105123 response .sendError (HttpServletResponse .SC_UNAUTHORIZED , "Unauthorized: Invalid or missing token" );
106-
124+
107125 } catch (Exception e ) {
108126 logger .error ("Authorization error: " , e );
109127 response .sendError (HttpServletResponse .SC_UNAUTHORIZED , "Authorization error: " + e .getMessage ());
110128 }
111129 }
130+
131+ private boolean isOriginAllowed (String origin ) {
132+ if (origin == null || allowedOrigins == null || allowedOrigins .trim ().isEmpty ()) {
133+ logger .warn ("No allowed origins configured or origin is null" );
134+ return false ;
135+ }
136+
137+ return Arrays .stream (allowedOrigins .split ("," ))
138+ .map (String ::trim )
139+ .anyMatch (pattern -> {
140+ String regex = pattern
141+ .replace ("." , "\\ ." )
142+ .replace ("*" , ".*" )
143+ .replace ("http://localhost:.*" , "http://localhost:\\ d+" ); // special case for wildcard port
144+
145+ boolean matched = origin .matches (regex );
146+ return matched ;
147+ });
148+ }
149+
112150 private boolean isMobileClient (String userAgent ) {
113151 if (userAgent == null )
114152 return false ;
115153 userAgent = userAgent .toLowerCase ();
116154 return userAgent .contains (Constants .OKHTTP );
117155 }
156+
118157 private String getJwtTokenFromCookies (HttpServletRequest request ) {
119158 Cookie [] cookies = request .getCookies ();
120159 if (cookies != null ) {
0 commit comments