java - 在 Tomcat servlet 中处理重复的 GET 请求(由 Trendmicro 引起)

标签 java tomcat servlets

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

基本上,我得到的是相隔几秒钟的 2 个请求,第一个来自客户端的真实 IP,第二个来自 TrendMicro 服务器(这似乎与描述的效果相同 here

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

所以问题是,我怎样才能阻止第二个请求?或者有没有其他策略可以解决这个问题?

谢谢!

最佳答案

所以我刚刚发现这也在我的网站上引起了问题。我存储了客户在 session 中请求的当前信息,但我收到了看似随机情况的报告,在这些情况下,用户会查看一个客户的信息,去查看另一个客户的信息,添加评论,但评论结束了1日客户记录。

我今天找到了罪魁祸首。它是 TrendMicro,在真实用户查看第二个客户信息和添加评论之间反射(reflect)对第一个客户记录的调用。他们还欺骗了 cookie,这是主要问题。

即。 1) 真实IP调用Customer 1信息(信息存储在session中)

2) 真实 IP 调用客户 2 信息(信息存储在 session 中,替换客户 1 信息)

3) TrendMicro IP 调用客户 1 信息(信息存储在 session 中,替换客户 2 信息)

4) Real IP 添加评论,该评论被添加到存储在 session 中的客户,感谢 TrendMicro,现在是客户 1。

解决方案? - 我添加了一个检查以确保我们只为来自登录 IP 地址的调用提供服务。

为此,您需要做两件事。

1) 在您的登录代码中,在您验证登录凭据后,使用以下代码将用户 IP 地址存储在 session 中:

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

接下来,编写一个实现javax.servlet.Filter接口(interface)的类。

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").equals(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)

关于java - 在 Tomcat servlet 中处理重复的 GET 请求(由 Trendmicro 引起),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28353652/

相关文章:

java - 在另一个 java 类中使用变量/数组。合并简单的java文件?

java - 如何进行 ssl 套接字编程

java - 如何将 Spring Bean 的生命周期与 Web 应用程序的生命周期联系起来?

java - 使用 HTTPservletResponse 发送对象

Java servlet - HTTP 状态 405 - 此 URL 不支持 HTTP 方法 GET/POST

java - 无法在eclipse中设置共享库路径

java - Maven:将未知的 jar 文件导入存储库

java - 为什么 Tomcat 8 不会在创建后立即将 session 持久保存到数据存储区?

Tomcat 无法启动应用程序并超时——日志中的最后一行只是单词 "bad"

java - HTTP 状态 500 包装器找不到 servlet 类