Java Spring SecurityContext获取;“丢失”;

Java Spring SecurityContext获取;“丢失”;,java,spring,spring-mvc,spring-security,security-context,Java,Spring,Spring Mvc,Spring Security,Security Context,我正在开发一个遗留应用程序(Spring 2.2.5、Spring Security 2.0.8)。身份验证由自定义预验证ProcessingFilter实现,其中SecurityContext由身份验证对象填充。此身份验证在大多数地方都可用(无论是直接SecurityContextHolder调用,还是AccessDecisionManager/AfterInvocationProvider参数)。但是,有些地方的身份验证对象(由SecurityContextHolder访问)为空。真正奇怪的

我正在开发一个遗留应用程序(Spring 2.2.5、Spring Security 2.0.8)。身份验证由自定义预验证ProcessingFilter实现,其中SecurityContext由身份验证对象填充。此身份验证在大多数地方都可用(无论是直接SecurityContextHolder调用,还是AccessDecisionManager/AfterInvocationProvider参数)。但是,有些地方的身份验证对象(由SecurityContextHolder访问)为空。真正奇怪的是,这发生在单个Http请求中。类A获取身份验证对象,类B,稍后在堆栈中调用获取null。当然,这发生在同一个线程中,排除了这个问题最简单的答案。看起来,尽管线程是相同的SecurityContextHolder,但它返回不同的SecurityContext对象(SecurityContext.toString()返回不同的内存地址)。重要的是,发生这种情况的地方不是你通常的春豆。这是一个相当自定义的模块子系统,涉及到自定义类加载器,我认为这可能与这种奇怪的效果有关


所以问题是:除了生成不同的线程之外,还有什么会导致SecurityContextHolder“丢失”SecurityContext对象?

这里的关键问题是SecurityContextHolder使用ThreadLocal,而我的子系统使用自定义类加载器。由自定义类加载器创建的类内调用的SecurityContextHolder将导致该类加载器加载SecurityContextHolder类并使用空上下文初始化它,从而产生上述效果

因此,简而言之,ThreadLocal和自定义类装入器不能很好地混合,如下所述: