2015-02-05 65 views
0

在Apache Tomcat servlet中处理来自同一客户端的重复GET请求的最佳策略是什么?在Tomcat servlet中处理重复GET请求(由Trendmicro引起)

基本上,我越来越有2请求的几秒钟分开,从客户端的真实IP第一,从趋势科技服务器第2(这似乎是描述here是同样的效果。

现在我的servlet忠实地服务于这两个请求,但稍后会产生问题(因为它调用另一个远程服务,这很可能无法处理这种情况)

所以问题是,如何阻止第二个请求?任何其他策略来解决这个问题?

谢谢!

回答

0

如果你的servlet直接为请求提供服务,一个简单的rate limiting filter可以做到这一点 - 而不是像这样使用会话来改变它使用传入请求方法+路径+ IP,然后为trendmicro ip创建第二个条目。

然而,正确的网络服务器通常更好,所以如果你有一个(例如nginx或apache),那么我会考虑在那里做,或者你可以简单地阻止TrendMicro IP地址(如果它来自同一个IP)

+0

好吧,我想这是一个有效的方法 - 尽管这意味着硬编码“冒犯性”Trendmicro IP(s)。 由于此服务仅由注册用户调用,因此我现在实现了一个过滤器,该过滤器使用用户的ID在第一个(实际)请求仍在运行时阻止重复请求。 – user1703668 2015-02-06 15:07:12

1

所以我刚刚发现,这也造成了我的网站上的问题。我存储了客户在会话中请求的当前信息,但我收到了一些看似随机情况的报告,其中用户将查看一个客户信息,查看其他客户信息,添加评论,但评论最终结束在第一客户记录。

我今天发现了罪魁祸首。它是趋势科技(TrendMicro),将真实用户查看第二客户信息和添加评论之间的第一个客户记录视为呼叫。他们也欺骗了cookie,这是主要问题。

IE浏览器。 1)真正的IP电话用户1个信息(信息被存储在会话)

2)实时IP呼叫客户2信息(信息被存储在会话,免去客户1个资讯)

3)趋势科技IP电话客户1信息(信息被存储在会话,免去客户2信息)

4)真正的IP加评论,这被添加到存储在会话,现在,多亏了趋势科技,为客户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> 

我的代码现在再次工作正常(不,谢谢趋势科技)