package org.owasp.security.logging.mdc;
import java.io.IOException;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.owasp.security.logging.mdc.plugins.IPAddressPlugin;
import org.owasp.security.logging.mdc.plugins.SessionPlugin;
import org.slf4j.MDC;
/**
* J2EE filter to add request information to the logging context. Adding data to
* the MDC is accomplished through implementations of the IPlugin interface.
*
* This filter adds the following information to the MDC:
*
* <ul>
* <li>%X{ipAddress} - The remote IP address of the request (using
* IPAddressPlugin)
* <li>%X{session} - A hash of the J2EE session ID (using SessionPlugin)
* <li>%X{productName} - A product name identifier (specified in web.xml)
* <li>%X{hostname} - The server hostname (from HttpServletRequest)
* <li>%X{locale} - The preferred Locale of the client (from
* HttpServletRequest.getLocale())
* </ul>
*
* @author August Detlefsen [augustd@codemagi.com]
* @see IPlugin
*/
public class MDCFilter implements Filter {
public static final String IPADDRESS = "ipAddress";
public static final String LOGIN_ID = "username";
public static final String SESSION = "session";
private static final String HOSTNAME = "hostName";
private static final String PRODUCTNAME = "productName";
private String productName;
private static final Map<String, IPlugin> plugins = new LinkedHashMap<String, IPlugin>();
static {
// set some defaults
plugins.put(IPADDRESS, new IPAddressPlugin());
plugins.put(SESSION, new SessionPlugin());
}
public void init(FilterConfig filterConfig) throws ServletException {
// process plugins in filter config
Enumeration<?> e = filterConfig.getInitParameterNames();
while (e.hasMoreElements()) {
String pluginName = (String) e.nextElement();
if ("ProductName".equals(pluginName)) {
productName = filterConfig.getInitParameter("ProductName");
} else {
// this is a plugin
try {
IPlugin plugin = (IPlugin) Class.forName(
filterConfig.getInitParameter(pluginName))
.newInstance();
plugin.init(filterConfig);
plugins.put(pluginName, plugin);
} catch (Exception cnfe) {
// ClassNotFoundException, InstantiationException,
// IllegalAccessException
cnfe.printStackTrace();
}
}
}
}
/**
* Sample filter that populates the MDC on every request.
*
* @param servletRequest
* The request to filter
* @param servletResponse
* The response to filter
* @param filterChain
* The filter chain for this context
*/
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
// put values into MDC
MDC.put(HOSTNAME, servletRequest.getServerName());
if (productName != null) {
MDC.put(PRODUCTNAME, productName);
}
MDC.put("locale", servletRequest.getLocale().getDisplayName());
// process plugins
for (IPlugin plugin : plugins.values()) {
plugin.execute(request);
}
// forward to the chain for processing
filterChain.doFilter(servletRequest, servletResponse);
MDC.clear();
}
public void destroy() {
}
}