# Concurrency Support In most environments, Security is stored on a per `Thread` basis. This means that when work is done on a new `Thread`, the `SecurityContext` is lost. Spring Security provides some infrastructure to help make this much easier for users. Spring Security provides low level abstractions for working with Spring Security in multi-threaded environments. In fact, this is what Spring Security builds on to integration with [AsyncContext.start(Runnable)](../../servlet/integrations/servlet-api.html#servletapi-start-runnable) and [Spring MVC Async Integration](../../servlet/integrations/mvc.html#mvc-async). ## DelegatingSecurityContextRunnable One of the most fundamental building blocks within Spring Security’s concurrency support is the `DelegatingSecurityContextRunnable`. It wraps a delegate `Runnable` in order to initialize the `SecurityContextHolder` with a specified `SecurityContext` for the delegate. It then invokes the delegate Runnable ensuring to clear the `SecurityContextHolder` afterwards. The `DelegatingSecurityContextRunnable` looks something like this: Java ``` public void run() { try { SecurityContextHolder.setContext(securityContext); delegate.run(); } finally { SecurityContextHolder.clearContext(); } } ``` Kotlin ``` fun run() { try { SecurityContextHolder.setContext(securityContext) delegate.run() } finally { SecurityContextHolder.clearContext() } } ``` While very simple, it makes it seamless to transfer the SecurityContext from one Thread to another. This is important since, in most cases, the SecurityContextHolder acts on a per Thread basis. For example, you might have used Spring Security’s [\](../../servlet/appendix/namespace/method-security.html#nsa-global-method-security) support to secure one of your services. You can now easily transfer the `SecurityContext` of the current `Thread` to the `Thread` that invokes the secured service. An example of how you might do this can be found below: Java ``` Runnable originalRunnable = new Runnable() { public void run() { // invoke secured service } }; SecurityContext context = SecurityContextHolder.getContext(); DelegatingSecurityContextRunnable wrappedRunnable = new DelegatingSecurityContextRunnable(originalRunnable, context); new Thread(wrappedRunnable).start(); ``` Kotlin ``` val originalRunnable = Runnable { // invoke secured service } val context: SecurityContext = SecurityContextHolder.getContext() val wrappedRunnable = DelegatingSecurityContextRunnable(originalRunnable, context) Thread(wrappedRunnable).start() ``` The code above performs the following steps: * Creates a `Runnable` that will be invoking our secured service. Notice that it is not aware of Spring Security * Obtains the `SecurityContext` that we wish to use from the `SecurityContextHolder` and initializes the `DelegatingSecurityContextRunnable` * Use the `DelegatingSecurityContextRunnable` to create a Thread * Start the Thread we created Since it is quite common to create a `DelegatingSecurityContextRunnable` with the `SecurityContext` from the `SecurityContextHolder` there is a shortcut constructor for it. The following code is the same as the code above: Java ``` Runnable originalRunnable = new Runnable() { public void run() { // invoke secured service } }; DelegatingSecurityContextRunnable wrappedRunnable = new DelegatingSecurityContextRunnable(originalRunnable); new Thread(wrappedRunnable).start(); ``` Kotlin ``` val originalRunnable = Runnable { // invoke secured service } val wrappedRunnable = DelegatingSecurityContextRunnable(originalRunnable) Thread(wrappedRunnable).start() ``` The code we have is simple to use, but it still requires knowledge that we are using Spring Security. In the next section we will take a look at how we can utilize `DelegatingSecurityContextExecutor` to hide the fact that we are using Spring Security. ## DelegatingSecurityContextExecutor In the previous section we found that it was easy to use the `DelegatingSecurityContextRunnable`, but it was not ideal since we had to be aware of Spring Security in order to use it. Let’s take a look at how `DelegatingSecurityContextExecutor` can shield our code from any knowledge that we are using Spring Security. The design of `DelegatingSecurityContextExecutor` is very similar to that of `DelegatingSecurityContextRunnable` except it accepts a delegate `Executor` instead of a delegate `Runnable`. You can see an example of how it might be used below: Java ``` SecurityContext context = SecurityContextHolder.createEmptyContext(); Authentication authentication = new UsernamePasswordAuthenticationToken("user","doesnotmatter", AuthorityUtils.createAuthorityList("ROLE_USER")); context.setAuthentication(authentication); SimpleAsyncTaskExecutor delegateExecutor = new SimpleAsyncTaskExecutor(); DelegatingSecurityContextExecutor executor = new DelegatingSecurityContextExecutor(delegateExecutor, context); Runnable originalRunnable = new Runnable() { public void run() { // invoke secured service } }; executor.execute(originalRunnable); ``` Kotlin ``` val context: SecurityContext = SecurityContextHolder.createEmptyContext() val authentication: Authentication = UsernamePasswordAuthenticationToken("user", "doesnotmatter", AuthorityUtils.createAuthorityList("ROLE_USER")) context.authentication = authentication val delegateExecutor = SimpleAsyncTaskExecutor() val executor = DelegatingSecurityContextExecutor(delegateExecutor, context) val originalRunnable = Runnable { // invoke secured service } executor.execute(originalRunnable) ``` The code performs the following steps: * Creates the `SecurityContext` to be used for our `DelegatingSecurityContextExecutor`. Note that in this example we simply create the `SecurityContext` by hand. However, it does not matter where or how we get the `SecurityContext` (i.e. we could obtain it from the `SecurityContextHolder` if we wanted). * Creates a delegateExecutor that is in charge of executing submitted `Runnable`s * Finally we create a `DelegatingSecurityContextExecutor` which is in charge of wrapping any Runnable that is passed into the execute method with a `DelegatingSecurityContextRunnable`. It then passes the wrapped Runnable to the delegateExecutor. In this instance, the same `SecurityContext` will be used for every Runnable submitted to our `DelegatingSecurityContextExecutor`. This is nice if we are running background tasks that need to be run by a user with elevated privileges. * At this point you may be asking yourself "How does this shield my code of any knowledge of Spring Security?" Instead of creating the `SecurityContext` and the `DelegatingSecurityContextExecutor` in our own code, we can inject an already initialized instance of `DelegatingSecurityContextExecutor`. Java ``` @Autowired private Executor executor; // becomes an instance of our DelegatingSecurityContextExecutor public void submitRunnable() { Runnable originalRunnable = new Runnable() { public void run() { // invoke secured service } }; executor.execute(originalRunnable); } ``` Kotlin ``` @Autowired lateinit var executor: Executor // becomes an instance of our DelegatingSecurityContextExecutor fun submitRunnable() { val originalRunnable = Runnable { // invoke secured service } executor.execute(originalRunnable) } ``` Now our code is unaware that the `SecurityContext` is being propagated to the `Thread`, then the `originalRunnable` is run, and then the `SecurityContextHolder` is cleared out. In this example, the same user is being used to run each thread. What if we wanted to use the user from `SecurityContextHolder` at the time we invoked `executor.execute(Runnable)` (i.e. the currently logged in user) to process `originalRunnable`? This can be done by removing the `SecurityContext` argument from our `DelegatingSecurityContextExecutor` constructor. For example: Java ``` SimpleAsyncTaskExecutor delegateExecutor = new SimpleAsyncTaskExecutor(); DelegatingSecurityContextExecutor executor = new DelegatingSecurityContextExecutor(delegateExecutor); ``` Kotlin ``` val delegateExecutor = SimpleAsyncTaskExecutor() val executor = DelegatingSecurityContextExecutor(delegateExecutor) ``` Now anytime `executor.execute(Runnable)` is executed the `SecurityContext` is first obtained by the `SecurityContextHolder` and then that `SecurityContext` is used to create our `DelegatingSecurityContextRunnable`. This means that we are running our `Runnable` with the same user that was used to invoke the `executor.execute(Runnable)` code. ## Spring Security Concurrency Classes Refer to the Javadoc for additional integrations with both the Java concurrent APIs and the Spring Task abstractions. They are quite self-explanatory once you understand the previous code. * `DelegatingSecurityContextCallable` * `DelegatingSecurityContextExecutor` * `DelegatingSecurityContextExecutorService` * `DelegatingSecurityContextRunnable` * `DelegatingSecurityContextScheduledExecutorService` * `DelegatingSecurityContextSchedulingTaskExecutor` * `DelegatingSecurityContextAsyncTaskExecutor` * `DelegatingSecurityContextTaskExecutor` * `DelegatingSecurityContextTaskScheduler`