سؤال

I'm working on a legacy app (Spring 2.2.5, Spring Security 2.0.8). Authentication is achieved by custom PreAuthenticationProcessingFilter, where SecurityContext is populated with Authentication object. This authentication is available in most places (be it direct SecurityContextHolder call, or AccessDecisionManager/AfterInvocationProvider arguments). However there are places where Authentication object (accessed by SecurityContextHolder) is null. What is really bizzare is that this happens within single Http request. Class A gets Authentication object, Class B, called later in the stack gets null. Naturally, this happens within the same thread which rules out the simpliest answer to this problem. It appears that despite the thread being the same SecurityContextHolder returns different SecurityContext objects (SecurityContext.toString() returns different memory addresses). What is important is that the place where this happens is not your usual Spring bean. This is a rather custom module subsystem with custom class loader involved and I think that this might have to do something with this bizzare effect.

So the question is: What, besides spawning different thread can cause SecurityContextHolder to "lose" SecurityContext object?

هل كانت مفيدة؟

المحلول

The key issue here was SecurityContextHolder using ThreadLocal and my subsystem using custom class loader. SecurityContextHolder called within a class, created by custom class loader will cause that class loader to load SecurityContextHolder class and initialize it with empty context, hence the effect described above.

So in short, ThreadLocal and custom class loaders do not mix well, as described here:

Effect of ThreadLocals and side-by-side classloading

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top