我正在开发基于Java的Web应用程序,我们使用ThreadLocal来跟踪当前登录的用户。现在,通常它完全正常。但是,只要存在会话超时,并且系统尝试访问该变量(来自ThreadLocal数据),它就会给出随机值(某些其他登录用户的值)。理想情况下,它应该返回一个空值。我很困惑这里发生了什么。
答案 0 :(得分:1)
线程是汇集的,因此您需要确保为每个请求清除ThreadLocal。如果你在Filter中执行此操作,它可能看起来像这样:
private static final ThreadLocal<String> CONTEXT = new ThreadLocal<String>();
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
try {
CONTEXT.set(userName);
chain.doFilter(req,res);
} finally {
CONTEXT.remove();
}
}
否则会发生什么:
这不仅是一个安全问题,而且还是内存泄漏。虽然每个用户填充的线程只有一个看起来很小,但它可以加起来。此外,如果放置在ThreadLocal中的对象是该类型属于war的ClassLoader的对象,则每次取消部署/部署应用程序时都会有一个大的PermGen leak泄漏整个战争内容而不重新启动应用程序服务器
@LaurentG是正确的,使用Spring Security的方法是使用SecurityContextHolder。您可以看到SecurityContextPersistenceFilter确保finally块中的SecurityContext gets cleared out。