ThreadLocal共享数据?

时间:2013-02-07 06:57:48

标签: java tomcat servlet-filters thread-local esapi

无论如何,我知道以下是不可能的,但它发生在我们的一个生产环境中:

SETUP

  • ESAPI 2.01
  • 主servlet过滤器设置和删除当前请求线程本地对象:

    try {
        ESAPI.httpUtilities().setCurrentHTTP(request, response);
    
        // filter logic ...
    } catch (Exception e) {
        LOG.error(Logger.SECURITY_FAILURE, "Error in ESAPI "
                + "security filter: " + e.getMessage(), e);
        request.setAttribute("message", e.getMessage());
    } finally {
        ESAPI.clearCurrent();
    }
    

所有请求都通过此过滤器,整个系统都使用ESAPI.currentRequest()

  • 路径A(http://server/path_a/
    • 一直到达method_a,无法从path_b
    • 访问此方法
  • 路径B(http://server/path_b
    • 一直到method_b,无法从path_a
    • 访问

这两个路径都通过servlet过滤器(映射“/*”)

我收到的一封错误邮件表明path_a正在抛出错误,而这又发起了错误邮件,在邮件代码中,当前请求(通过ESAPI.currentRequest())被枚举为请求信息。

问题

在错误邮件中,来自path_a的请求信息与来自method_b的堆栈跟踪信息相关联,对我来说这似乎是不可能的,因为它们都在不同的线程中运行。

问题

这怎么可能?我无法在本地重新创建,除了设置和清除ThreadLocal之外,我还需要采取一些预防措施吗?这可能是tomcat设置的问题吗?我输了。


PS:问题的代码已经简化,因为代码库很大,例如


error mail

1 个答案:

答案 0 :(得分:2)

阅读ESAPI代码https://code.google.com/p/owasp-esapi-java/source/browse/trunk/src/main/java/org/owasp/esapi/reference/DefaultHTTPUtilities.java有一些关于本地线程的可疑实践。

我说的最大问题是它使用InheritableThreadLocal。如果线程A产生一个线程B,B将继承A的线程局部值;然而,当A然后清除本地线程时,它不会影响B,因此B的继承值将保留。 ESAPI可能不应该使用InheritableThreadLocal

我无法说明这可能会产生您看到的问题,而无需了解应用中的线程。