Package com.googlecode.righettod.pdec

Source Code of com.googlecode.righettod.pdec.ActiveDetectionFilter

package com.googlecode.righettod.pdec;

import java.io.IOException;
import java.sql.SQLException;
import java.util.concurrent.TimeUnit;

import javax.cache.Cache;
import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.Duration;
import javax.cache.expiry.TouchedPolicy;
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.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Filter managing detection of active profiling.
*
* @author Dominique Righetto (dominique.righetto@gmail.com)
*
*/
@WebFilter("/*")
public class ActiveDetectionFilter implements Filter {

  /** LOGGER */
  private static final Logger LOG = LoggerFactory.getLogger(ActiveDetectionFilter.class);

  /** Name of fake cookie used */
  private static final String FAKE_COOKIE_NAME = "verbose_mode";

  /** Value of fake cookie used */
  private static final String FAKE_COOKIE_VALUE = "false";

  /** Blocked sender cache. */
  private CacheManager cacheManager = null;
  private Cache<String, Boolean> blockedSenderCache = null;

  /**
   * {@inheritDoc}
   *
   * @see javax.servlet.Filter#destroy()
   */
  @Override
  public void destroy() {
    this.blockedSenderCache.close();
    this.cacheManager.close();
  }

  /**
   * {@inheritDoc}
   *
   * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
   */
  @Override
  public void init(FilterConfig fc) throws ServletException {
    // Initialize the cache for the Blocked sender list: put the retention to 1 hour
    this.cacheManager = Caching.getCachingProvider().getCacheManager();
    MutableConfiguration<String, Boolean> config = new MutableConfiguration<>();
    config.setExpiryPolicyFactory(TouchedPolicy.factoryOf(new Duration(TimeUnit.HOURS, Long.parseLong("1"))));
    this.cacheManager.configureCache("CacheBlockedSender", config);
    this.blockedSenderCache = this.cacheManager.getCache("CacheBlockedSender");

  }

  /**
   * {@inheritDoc}
   *
   * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
   */
  @Override
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain fChain) throws IOException, ServletException {
    HttpServletRequest hReq = (HttpServletRequest) req;
    HttpServletResponse hResp = (HttpServletResponse) resp;

    try {
      /* Step 1a: Generate Unique Identifier for current request */
      LOG.info("ActiveDetectionFilter::Step01a");
      String visitorId = Utils.generateID(hReq);

      /* Step 1b: Check if the sender is into the blocked sender cache */
      LOG.info("ActiveDetectionFilter::Step01b");
      if (this.blockedSenderCache.containsKey(visitorId)) {
        LOG.info("===> '{}' blocked !", visitorId);
        hResp.sendError(HttpServletResponse.SC_FORBIDDEN);
        return;
      }

      /* Step 2: Check if fake cookie is present into request, if yes grab value during check */
      LOG.info("ActiveDetectionFilter::Step02");
      String fakeCookieValue = "";
      if (hReq.getCookies() != null) {
        for (Cookie c : hReq.getCookies()) {
          // Explicitly concat value in case of multi submit of same cookie name
          if (FAKE_COOKIE_NAME.equalsIgnoreCase(c.getName())) {
            fakeCookieValue = fakeCookieValue.concat(c.getValue());
          }
        }
      }

      /* Step 3: Check if we are received or not the cookie */
      LOG.info("ActiveDetectionFilter::Step03");
      // If we have received the value we check the values against the expected values
      if (!"".equals(fakeCookieValue) && !fakeCookieValue.equalsIgnoreCase(FAKE_COOKIE_VALUE)) {
        // Cookie value has been modified
        // Send warning to to a monitoring system
        this.sendWarningAboutVisitor(hReq, visitorId);
        // Stop request in processing flow
        LOG.info("===> '{}' stopped !", visitorId);
        hResp.sendError(HttpServletResponse.SC_FORBIDDEN);
        return;
      }
      // If we have received nothing we assume that is the first call of the sender
      // the we create the value and cookie
      Cookie c = new Cookie(FAKE_COOKIE_NAME, FAKE_COOKIE_VALUE);
      c.setMaxAge(86400);// 1 day
      c.setHttpOnly(true);// Explicitly secure it
      hResp.addCookie(c);
      LOG.info("===> Cookie issued to '{}'.", visitorId);

      // Continue filter chain
      LOG.info("ActiveDetectionFilter::Out");
      fChain.doFilter(req, resp);
    }
    catch (Exception e) {
      throw new ServletException("Unable to correctly handle current request !", e);
    }
  }

  /**
   * Method to send warning to to a monitoring system in order to generate an alert and launch a review <br>
   * of the sender information in order to decide if aggressive defensive measure should be taken against him.<br>
   * Here, for the example, we simply add the visitor to the blocked sender cache.
   *
   * @param req HTTP request information.
   * @param visitorId Visitor unique ID generated to track it.
   * @throws SQLException
   */
  @SuppressWarnings({ "unused" })
  private void sendWarningAboutVisitor(HttpServletRequest req, String visitorId) throws SQLException {
    LOG.warn("ActiveDetectionFilter::Warning sent for visitor '{}'.", visitorId);
    // Add the visitor to the blocked sender cache.
    this.blockedSenderCache.put(visitorId, Boolean.TRUE);
  }
}
TOP

Related Classes of com.googlecode.righettod.pdec.ActiveDetectionFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.