我正在开发一个遗留应用程序(Spring 2.2.5,Spring Security 2.0.8)。身份验证由自定义PreAuthenticationProcessingFilter实现,其中SecurityContext使用Authentication对象填充。此身份验证在大多数地方都可用(无论是直接SecurityContextHolder调用,还是AccessDecisionManager / AfterInvocationProvider参数)。但是,有些地方认证对象(由SecurityContextHolder访问)为空。真正令人头晕的是,这发生在单个Http请求中。 A类获取Authentication对象,Class B,稍后在堆栈中调用获取null。当然,这发生在同一个线程中,它排除了这个问题的最简单答案。看来尽管线程是相同的SecurityContextHolder返回不同的SecurityContext对象(SecurityContext.toString()返回不同的内存地址)。重要的是发生这种情况的地方不是通常的Spring bean。这是一个相当自定义的模块子系统,包含自定义类加载器,我认为这可能需要对这种混淆效果做些什么。
所以问题是:什么,除了产生不同的线程可以导致SecurityContextHolder“丢失”SecurityContext对象?
答案 0 :(得分:0)
这里的关键问题是使用ThreadLocal的SecurityContextHolder和使用自定义类加载器的子系统。在一个类中调用的SecurityContextHolder,由自定义类加载器创建,将导致该类加载器加载SecurityContextHolder类并使用空上下文初始化它,因此产生上述效果。
简而言之,ThreadLocal和自定义类加载器混合不好,如下所述: