2015-02-05 2 views
0

Какова лучшая стратегия решения дублирующих запросов GET, исходящих от одного и того же клиента в сервлет Apache Tomcat?Обработка дублированных запросов GET (вызванных Trendmicro) в сервлете Tomcat

В общем, что я получаю в 2 запроса на пару секунд друг от друга, первые из реальных IP клиента, то вторые с сервером TrendMicro (это, кажется, тот же эффект, как описано here.

Теперь мой сервлет верно обслуживает оба запроса, но потом создает проблемы (потому что он вызывает другую удаленную услугу, которая, скорее всего, тоже не может справиться с этой ситуацией).

Итак, вопрос в том, как я могу заблокировать второй запрос? любая другая стратегия для решения этой проблемы?

Спасибо!

ответ

0

Если ваш сервлет обслуживает запросы напрямую, то простой rate limiting filter выполнит трюк - вместо использования сеанса, подобного этому, измените его на использование метода входящих запросов + путь + ip, а затем создайте вторую запись для trendmicro ip.

Однако подходящие веб-серверы обычно лучше подходят для этого, поэтому, если у вас есть один (например, nginx или apache), я бы посмотрел на это, или вы можете просто заблокировать адрес TrendMicro IP (если он поступает с одного и того же IP-адреса)

+0

Хорошо, я полагаю, что это действительный подход - хотя это будет означать жесткое кодирование «оскорбительных» Trendmicro IP-адресов. Поскольку эта услуга вызывается только зарегистрированными пользователями, теперь я реализовал фильтр, который использует идентификатор пользователя для блокировки повторяющихся запросов, пока первый (реальный) запрос все еще запущен. – user1703668

1

Так что я только что нашел, что это вызывает проблемы и на моем сайте. Я сохраняю текущую информацию, которую клиент запросил в сеансе, но я получал сообщения о кажущихся случайными ситуациях, когда пользователь просматривал информацию о клиентах, отправлял информацию о других клиентах, добавлял комментарий, но комментарий заканчивается по 1-й записи клиентов.

Я нашел преступника сегодня. Это TrendMicro, отражающий вызов первой записи клиентов между реальным пользователем, просматривающим вторую информацию о клиентах и ​​добавлением комментария. Они также подделывают файл cookie, что является основной проблемой.

Т.е. 1) Реальный IP вызовы клиентов 1 данные (информация сохраняется в сессии)

2) Реальный IP клиент звонит 2 данные (информация сохраняется в сессии, заменив заказчик 1 информация)

3) TrendMicro IP вызовы клиентов 1 Информация (информация сохраняется в сессии, заменив клиента 2) Информация

4) Реальный IP добавляет комментарий, который будет добавлен к клиенту, хранящегося в сессии, которая в настоящее время, благодаря TrendMicro, является Клиент 1.

Решение? - Я добавил чек, чтобы гарантировать, что мы обслуживаем только исходящие из IP-адреса, которые вошли в систему.

Для этого вам нужно сделать 2 вещи.

1) На ваш код авторизации, после того как вы проверены учетные данные для входа, сохраните пользователям IP-адрес в сессии, используя этот код:

session.setAttribute("LoginIPAddress", request.getRemoteAddr()); 

Далее, написать класс, который реализует javax.servlet. Фильтрующий интерфейс.

import java.io.IOException; 
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.HttpSession; 
public class ServletUserAuthenticationFilter implements Filter { 


    // ----------------------------------------------------- Instance Variables 


    /** 
    * The default character forwardTo to set for requests that pass through 
    * this filter. 
    */ 
    protected String forwardTo = null; 


    /** 
    * Take this filter out of service. 
    */ 
    public void destroy() { 
     this.forwardTo = null; 
    } 

    /** 
    * Select and set (if specified) the character forwardTo to be used to 
    * interpret request parameters for this request. 
    * 
    * @param request The servlet request we are processing 
    * @param result The servlet response we are creating 
    * @param chain The filter chain we are processing 
    * 
    * @exception IOException if an input/output error occurs 
    * @exception ServletException if a servlet error occurs 
    */ 
    public void doFilter(ServletRequest request, ServletResponse response, 
         FilterChain chain) 
    throws IOException, ServletException { 

     javax.servlet.http.HttpServletRequest httpRequest = (javax.servlet.http.HttpServletRequest)request; 
     HttpSession session = httpRequest.getSession(); 

     // Is there a valid session? 
     // We now also redirect requests if the remote IP Address is not the same address that originally signed in 
     if(!httpRequest.getRequestURI().equals(httpRequest.getContextPath()+"/services/login") && !httpRequest.getRequestURI().equals(httpRequest.getContextPath()+"/services/logout") 
       && (((session==null || session.getAttribute("userData")==null)) 
       || (session!=null && session.getAttribute("LoginIPAddress")!=null && !session.getAttribute("LoginIPAddress").equals(httpRequest.getRemoteAddr())))){ 
      // An Https page has been requested, but no valid session has been found, ao forward the user to the page indicated by forwardTo 
      javax.servlet.http.HttpServletResponse httpResponse = (javax.servlet.http.HttpServletResponse)response; 
      StringBuffer logonQuery = new StringBuffer(); 
      logonQuery.append(httpRequest.getScheme()); 
      logonQuery.append("://"); 
      logonQuery.append(request.getServerName()); 
      logonQuery.append(":"); 
      logonQuery.append(httpRequest.getLocalPort()); 
      logonQuery.append(httpRequest.getContextPath()); 
      logonQuery.append(forwardTo); 
      session = httpRequest.getSession(true); 
      session.setAttribute("MESSAGE", "Your session has expired. Please login again"); 
      httpResponse.sendRedirect(logonQuery.toString()); 
      return; 
     } 

     // Pass control on to the next filter 
     chain.doFilter(request, response); 

    } 


    /** 
    * Place this filter into service. 
    * 
    * @param filterConfig The filter configuration object 
    */ 
    public void init(FilterConfig filterConfig) throws ServletException { 

     this.forwardTo = filterConfig.getInitParameter("forwardTo"); 
    } 


} 

У меня есть некоторые дополнительные проверки в этом коде, который может не потребоваться, но главная проверка раздел! Session.getAttribute («LoginIPAddress»).равно (httpRequest.getRemoteAddr())

Наконец, вам необходимо сделать этот код работать каждый раз, когда сервер получает запрос, добавив в ваш web.xml

<filter> 
    <filter-name>Check User Has Logged In</filter-name> 
    <filter-class>au.com.mySystem.utils.filter.ServletUserAuthenticationFilter</filter-class> 
    <init-param> 
     <param-name>forwardTo</param-name> 
     <param-value>/pages/loginForwarder.jsp</param-value> 
    </init-param> 
    </filter> 

Мой код теперь работает правильно снова (Нет, спасибо TrendMicro)