[[servlet-authentication-securitycontextholder]] = SecurityContextHolder :figures: images/servlet/authentication/architecture At the heart of Spring Security's authentication model is the `SecurityContextHolder`. It contains the <>. image::{figures}/securitycontextholder.png[] The `SecurityContextHolder` is where Spring Security stores the details of who is <>. Spring Security does not care how the `SecurityContextHolder` is populated. If it contains a value, then it is used as the currently authenticated user. The simplest way to indicate a user is authenticated is to set the `SecurityContextHolder` directly. .Setting `SecurityContextHolder` ==== .Java [source,java,role="primary"] ---- SecurityContext context = SecurityContextHolder.createEmptyContext(); // <1> Authentication authentication = new TestingAuthenticationToken("username", "password", "ROLE_USER"); // <2> context.setAuthentication(authentication); SecurityContextHolder.setContext(context); // <3> ---- .Kotlin [source,kotlin,role="secondary"] ---- val context: SecurityContext = SecurityContextHolder.createEmptyContext() // <1> val authentication: Authentication = TestingAuthenticationToken("username", "password", "ROLE_USER") // <2> context.authentication = authentication SecurityContextHolder.setContext(context) // <3> ---- ==== <1> We start by creating an empty `SecurityContext`. It is important to create a new `SecurityContext` instance instead of using `SecurityContextHolder.getContext().setAuthentication(authentication)` to avoid race conditions across multiple threads. <2> Next we create a new <> object. Spring Security does not care what type of `Authentication` implementation is set on the `SecurityContext`. Here we use `TestingAuthenticationToken` because it is very simple. A more common production scenario is `UsernamePasswordAuthenticationToken(userDetails, password, authorities)`. <3> Finally, we set the `SecurityContext` on the `SecurityContextHolder`. Spring Security will use this information for <>. If you wish to obtain information about the authenticated principal, you can do so by accessing the `SecurityContextHolder`. .Access Currently Authenticated User ==== .Java [source,java,role="primary"] ---- SecurityContext context = SecurityContextHolder.getContext(); Authentication authentication = context.getAuthentication(); String username = authentication.getName(); Object principal = authentication.getPrincipal(); Collection authorities = authentication.getAuthorities(); ---- .Kotlin [source,kotlin,role="secondary"] ---- val context = SecurityContextHolder.getContext() val authentication = context.authentication val username = authentication.name val principal = authentication.principal val authorities = authentication.authorities ---- ==== // FIXME: add links to HttpServletRequest.getRemoteUser() and @CurrentSecurityContext @AuthenticationPrincipal By default the `SecurityContextHolder` uses a `ThreadLocal` to store these details, which means that the `SecurityContext` is always available to methods in the same thread, even if the `SecurityContext` is not explicitly passed around as an argument to those methods. Using a `ThreadLocal` in this way is quite safe if care is taken to clear the thread after the present principal's request is processed. Spring Security's <> ensures that the `SecurityContext` is always cleared. Some applications aren't entirely suitable for using a `ThreadLocal`, because of the specific way they work with threads. For example, a Swing client might want all threads in a Java Virtual Machine to use the same security context. `SecurityContextHolder` can be configured with a strategy on startup to specify how you would like the context to be stored. For a standalone application you would use the `SecurityContextHolder.MODE_GLOBAL` strategy. Other applications might want to have threads spawned by the secure thread also assume the same security identity. This is achieved by using `SecurityContextHolder.MODE_INHERITABLETHREADLOCAL`. You can change the mode from the default `SecurityContextHolder.MODE_THREADLOCAL` in two ways. The first is to set a system property, the second is to call a static method on `SecurityContextHolder`. Most applications won't need to change from the default, but if you do, take a look at the Javadoc for `SecurityContextHolder` to learn more.