Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Security and @Async (Authenticated Users mixed up)

I asynchronously invoke method with Spring, using @Async.This method invokes other method annotated with @PreAuthorize, Spring Security Annotation. To make authorization works I have to set SecurityContextHolder mode to MODE_INHERITABLETHREADLOCAL, so that authentication info is passed to the asynchronous call. Everything works fine so far.

However when I logout and login as a different user, in asynchronous method SecurityContextHolder stores authentication info of the old user, that has bee logged out. It causes of course unwanted AccessDenied exception. There is no such problem with synchronous calls.

I have defined <task:executor id="executors" pool-size="10"/>, so may it be a problem that once thread in executors pool has been initialized it will not override authentication information?

like image 928
Lukasz Moren Avatar asked Mar 09 '11 13:03

Lukasz Moren


People also ask

Does @async work on private methods?

Never use @Async on top of a private method. In runtime, it will not able to create a proxy and, therefore, not work. 3. Never write an Async method in the same class where the caller method invokes the same Async methodAsync method in the same class where the caller method invokes the same Async method.

How does @async work in Spring?

Simply put, annotating a method of a bean with @Async will make it execute in a separate thread. In other words, the caller will not wait for the completion of the called method. One interesting aspect in Spring is that the event support in the framework also has support for async processing if necessary.

Are Spring boots asynchronous?

Spring Boot uses a SimpleAsyncTaskExector to run an async method. This Executor runs by default and it can be overridden at two levels- at the individual method levels or at the application level.

What does @async annotation do in Spring boot?

The @EnableAsync annotation switches on Spring's ability to run @Async methods in a background thread pool. This class also customizes the Executor by defining a new bean. Here, the method is named taskExecutor , since this is the specific method name for which Spring searches.


1 Answers

I guess MODE_INHERITABLETHREADLOCAL doesn't work correctly with thread pool.

As a possible solution you can try to subclass ThreadPoolTaskExecutor and override its methods to propagate SecurityContext manually, and then declare that executor instead of <task:executor>, something like this:

public void execute(final Runnable r) {     final Authentication a = SecurityContextHolder.getContext().getAuthentication();      super.execute(new Runnable() {         public void run() {             try {                 SecurityContext ctx = SecurityContextHolder.createEmptyContext();                 ctx.setAuthentication(a);                 SecurityContextHolder.setContext(ctx);                 r.run();             } finally {                 SecurityContextHolder.clearContext();             }         }     }); } 
like image 196
axtavt Avatar answered Oct 06 '22 01:10

axtavt