RequestTracingFilter.java
package com.edtech.config;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;
import org.slf4j.MDC;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
/** Javadoc. */
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestTracingFilter extends OncePerRequestFilter {
private static final String TRACE_ID_HEADER = "X-Request-ID";
private static final String MDC_TRACE_ID_KEY = "traceId";
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
try {
String traceId = request.getHeader(TRACE_ID_HEADER);
if (traceId == null || traceId.isEmpty()) {
traceId = UUID.randomUUID().toString();
}
MDC.put(MDC_TRACE_ID_KEY, traceId);
// Sanitize before echoing back as HTTP header to prevent header injection (HRS)
String safeTraceId = traceId.replaceAll("[^a-zA-Z0-9\\-]", "");
response.setHeader(TRACE_ID_HEADER, safeTraceId);
filterChain.doFilter(request, response);
} finally {
MDC.remove(MDC_TRACE_ID_KEY);
}
}
}