// Copyright © 2015 HSL <https://www.hsl.fi> // This program is dual-licensed under the EUPL v1.2 and AGPLv3 licenses. package fi.hsl.parkandride; import fi.hsl.parkandride.front.IllegalHeaderException; import org.slf4j.MDC; import org.springframework.stereotype.Component; import org.springframework.web.filter.GenericFilterBean; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.UUID; import java.util.regex.Pattern; import static java.lang.String.format; @Component public class MDCFilter extends GenericFilterBean { public static final String LIIPI_APPLICATION_ID = "Liipi-Application-Id"; public static final Pattern APP_ID_PATTERN = Pattern.compile("[a-zA-Z0-9_\\-\\./]{3,20}"); public interface Key { String REQUESTID = "requestid"; String USERNAME = "username"; String SRCIP = "srcip"; String APPID = "appid"; } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { setValues(request); try { chain.doFilter(request, response); } finally { unsetValues(); } } private static void setValues(ServletRequest request) { HttpServletRequest httpReq = HttpServletRequest.class.cast(request); MDC.put(Key.REQUESTID, UUID.randomUUID().toString()); MDC.put(Key.SRCIP, httpReq.getRemoteHost()); // Authenticated username will be set in UserArgumentResolver iff authentication is required MDC.put(Key.USERNAME, "<ANONYMOUS>"); String appId = httpReq.getHeader(LIIPI_APPLICATION_ID); if (appId != null) { MDC.put(Key.APPID, appId); } } public static void validateAppId(String appId) { if (!APP_ID_PATTERN.matcher(appId).matches()) { throw new IllegalHeaderException( format("Illegal %s header. Value should match pattern %s.", LIIPI_APPLICATION_ID, APP_ID_PATTERN)); } } private static void unsetValues() { MDC.remove(Key.REQUESTID); MDC.remove(Key.USERNAME); MDC.remove(Key.SRCIP); MDC.remove(Key.APPID); } }