I\'m trying to get the user from spring context in an application spring as follows:
Authentication auth = SecurityContextHolder.getContext().getAuthenticati
Maybe this helps to get execute-method called (worked in my case):
@Override
@Bean(name = "asyncExecutor")
public Executor getAsyncExecutor() {
CustomThreadPoolTaskExecutor executor = new CustomThreadPoolTaskExecutor();
executor.setMaxPoolSize(1);
executor.setThreadGroupName("MyCustomExecutor");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setBeanName("asyncExecutor");
executor.initialize();
return new DelegatingSecurityContextAsyncTaskExecutor(executor);
}
Spring support for sending asynchronous requests with propagated SecurityContext. From a programming model perspective, the new capabilities appear deceptively simple. You can access to user info in async methods by setting security content strategy name in your security configurer class:
@Configuration
@EnableAsync
public class SpringAsyncConfig implements AsyncConfigurer {
public SpringAsyncConfig() {
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
}
}
This is my implementation, I've used TaskDecorator to copy the SecurityContext in the new thread, the new thread runs with this new SecurityContext even the user logout during the execution of the async task.
Xml declaration for executor
<bean id="securityContextCopyingDecorator" class="com.myapp.task.SecurityContextCopyingDecorator"/>
<bean id="threadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="1"/>
<property name="maxPoolSize" value="5"/>
<property name="queueCapacity" value="100"/>
<property name="taskDecorator" ref="securityContextCopyingDecorator"/>
</bean>
<task:annotation-driven executor="threadPoolTaskExecutor"/>
this is the class SecurityContextCopyingDecorator
package com.myapp.task;
import org.springframework.core.task.TaskDecorator;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
public class SecurityContextCopyingDecorator implements TaskDecorator {
@Override
public Runnable decorate(Runnable runnable) {
final Authentication a = SecurityContextHolder.getContext().getAuthentication();
return () -> {
try {
SecurityContext ctx = SecurityContextHolder.createEmptyContext();
ctx.setAuthentication(a);
SecurityContextHolder.setContext(ctx);
runnable.run();
} finally {
SecurityContextHolder.clearContext();
}
};
}
}
finally annotate some method to use threadPoolTaskExecutor in async mode
@Async
public void myAsyncMethod() {
}