From ab48d72cc26e92df12b63ccb555d219786186a74 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Sun, 6 Dec 2009 19:30:23 +0000 Subject: [PATCH] Extra doc info on sharing of SecurityContext between threads --- .../manual/src/docbook/technical-overview.xml | 63 ++++++++++++------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/docs/manual/src/docbook/technical-overview.xml b/docs/manual/src/docbook/technical-overview.xml index 5278c89d9a..fe2daa35a2 100644 --- a/docs/manual/src/docbook/technical-overview.xml +++ b/docs/manual/src/docbook/technical-overview.xml @@ -285,28 +285,29 @@ Successfully authenticated. Security context contains: \ Security has quite a simple answer. A user is authenticated when the SecurityContextHolder contains a fully populated Authentication object. -
- Setting the SecurityContextHolder Contents Directly - In fact, Spring Security doesn't mind how you put the - Authentication object inside the - SecurityContextHolder. The only critical requirement is that the - SecurityContextHolder contains an - Authentication that represents a principal before the - AbstractSecurityInterceptor (which we'll see more about later) - needs to authorize a user operation. - You can (and many users do) write their own filters or MVC controllers to provide - interoperability with authentication systems that are not based on Spring Security. For - example, you might be using Container-Managed Authentication which makes the current user - available from a ThreadLocal or JNDI location. Or you might work for a company that has a - legacy proprietary authentication system, which is a corporate "standard" over which you - have little control. In situations like this it's quite easy to get Spring Security to - work, and still provide authorization capabilities. All you need to do is write a filter - (or equivalent) that reads the third-party user information from a location, build a - Spring Security-specific Authentication object, and put it - into the SecurityContextHolder. - If you're wondering how the AuthenticationManager - manager is implemented in a real world example, we'll look at that in -
+ +
+ Setting the SecurityContextHolder Contents Directly + In fact, Spring Security doesn't mind how you put the + Authentication object inside the + SecurityContextHolder. The only critical requirement is that the + SecurityContextHolder contains an + Authentication which represents a principal before the + AbstractSecurityInterceptor (which we'll see more about later) + needs to authorize a user operation. + You can (and many users do) write their own filters or MVC controllers to provide + interoperability with authentication systems that are not based on Spring Security. For + example, you might be using Container-Managed Authentication which makes the current user + available from a ThreadLocal or JNDI location. Or you might work for a company that has a + legacy proprietary authentication system, which is a corporate "standard" over which you + have little control. In situations like this it's quite easy to get Spring Security to work, + and still provide authorization capabilities. All you need to do is write a filter (or + equivalent) that reads the third-party user information from a location, build a Spring + Security-specific Authentication object, and put it into the + SecurityContextHolder. + If you're wondering how the AuthenticationManager + manager is implemented in a real world example, we'll look at that in the core services chapter.
@@ -419,6 +420,24 @@ Successfully authenticated. Security context contains: \ that the SecurityContextPersistenceFilter is included in the chain to make sure that the SecurityContextHolder is cleared after each request. + + In an application which receives concurrent requests in a single session, the same + SecurityContext instance will be shared between threads. + Even though a ThreadLocal is being used, it is the same instance + that is retrieved from the HttpSession for each thread. + This has implications if you wish to temporarily change the context under which a thread + is running. If you just use + SecurityContextHolder.getContext().setAuthentication(anAuthentication), + then the Authentication object will change in + all concurrent threads which share the same + SecurityContext instance. You can customize the behaviour + of SecurityContextPersistenceFilter to create a completely new + SecurityContext for each request, preventing changes in + one thread from affecting another. Alternatively you can create a new instance just at the + point where you temporarily change the context. The method + SecurityContextHolder.createEmptyContext() always returns a new context + instance. +