Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring security's SecurityContextHolder: session or request bound?

Is the Userprincipal I retrieve from SecurityContextHolder bound to requests or to sessions?

UserPrincipal principal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();

This is the way I access the currently logged in user. Will this invalidate if the current session is destroyed?

like image 756
chzbrgla Avatar asked Jun 20 '11 07:06

chzbrgla


People also ask

What is SecurityContextHolder in spring?

The SecurityContextHolder is a helper class, which provide access to the security context. By default, it uses a ThreadLocal object to store security context, which means that the security context is always available to methods in the same thread of execution, even if you don't pass the SecurityContext object around.

Does Spring Security use session?

By default, Spring Security will create a session when it needs one — this is “ifRequired“. For a more stateless application, the “never” option will ensure that Spring Security itself won't create any session. But if the application creates one, Spring Security will make use of it.

Is SecurityContextHolder thread safe?

Yes, it's thread safe with the default strategy ( MODE_THREADLOCAL ) (as long as you don't try to change the strategy on the fly).

What is SecurityContextHolder getContext () getAuthentication ()?

The HttpServletRequest.getUserPrincipal() will return the result of SecurityContextHolder.getContext().getAuthentication() . This means it is an Authentication which is typically an instance of UsernamePasswordAuthenticationToken when using username and password based authentication.


1 Answers

It depends on how you configured it (or lets say, you can configure a different behaviour).

In a Web application you will use the ThreadLocalSecurityContextHolderStrategy which interacts with SecurityContextPersistenceFilter.

The Java Doc of SecurityContextPersistenceFilter starts with:

Populates the {@link SecurityContextHolder} with information obtained from the configured {@link SecurityContextRepository} prior to the request and stores it back in the repository once the request has completed and clearing the context holder. By default it uses an {@link HttpSessionSecurityContextRepository}. See this class for information HttpSession related configuration options.

Btw: HttpSessionSecurityContextRepository is the only implementation of SecurityContextRepository (I have found in the default libs)

It works like this:

  • The HttpSessionSecurityContextRepository uses the httpSession (Key="SPRING_SECURITY_CONTEXT") to store an SecurityContext Object.
  • The SecurityContextPersistenceFilter is an filter that uses an SecurityContextRepository for example the HttpSessionSecurityContextRepository to load and store SecurityContext Objects. If an HttpRequest passes the filter, the filter get the SecurityContext from the repository and put it in the SecurityContextHolder (SecurityContextHolder#setContext)
  • The SecurityContextHolder has two methods setContext and getContext. Both uses a SecurityContextHolderStrategy to specify what exactly is done in the set- and get-Context methods. - For example the ThreadLocalSecurityContextHolderStrategy uses a thread local to store the context.

So in summary: The user principal (element of SecurityContext) is stored in the HTTP Session. And for each request it is put in a thread local from where you access it.

like image 137
Ralph Avatar answered Sep 22 '22 15:09

Ralph