How Spring Security get currently logged in user in concept?
security, spring, spring-security
Solution
By default there are 3 important things here:
- HTTP session - stores authentication object between requests
- Servlet API filter - populates `SecurityContextHolder` before each request from HTTP session (and stores authentication object back once the request has completed)
- `ThreadLocal` - stores authentication object during request processing
After authentication corresponding `SecurityContext` object is stored in HTTP session. Before each request processing special `SecurityContextPersistenceFilter` is fired. It is responsible for loading of `SecurityContext` object from HTTP session (via `SecurityContextRepository` instance) and for injecting `SecurityContext` object into `SecurityContextHolder`. Take a look at the source code of `SecurityContextPersistenceFilter` class for more details. Another important part is that by default `SecurityContextHolder` stores `SecurityContext` object using `ThreadLocal` variable (so you will have a different authentication object per thread).
EDIT. Additional questions:
- HTTP session is saved in client's browser and updated between requests. No, HTTP session is stored in server side. It is linked to some user via session coockie (browser send this cookie during each request).
- SecurityContext, SecurityContextHolder and SecurityContextRepository are instances in Server side. They are used on server side. But `SecurityContextHolder` is not an instance, it is a helper class with static methods.
- ThreadLocal is a variable storing SecurityContextHolder which stores SecurityContext No, `SecurityContext` is stored in `ThreadLocal` variable. `SecurityContextHolder` is a helper class that may be used to get/set `SecurityContext` instance via `ThreadLocal` variable.
- If there are three connections, then there will be three SecurityContext object in Server. Yep.
- One SecurityContextHolder stores one SecurityContext No, the same static methods of `SecurityContextHolder` used by all threads to get/set corresponding `SecurityContext`.
- And suppose there are three SecurityContext instances in Server Side, how does it knows which one refers to that corresponding client? `ThreadLocal` variable has different values for different threads.
Problem
I get the currently logged in user by `SecurityContextHolder.getContext().getAuthentication()` in server side and do some logging on users. Here is the question: Suppose I have three user logged in. How the server side can identify the user just simply calling `SecurityContextHolder.getContext().getAuthentication();` ? Thanks for your reply.