How can I use spring-data-jpa (AuditorAware) auditing in asynchronous tasks?
Currently My AuditorAware
Implementation uses Spring SecurityContextHolder
to get the current auditor to store the create / modify names:
@Service
public class AuditorAwareImpl implements AuditorAware<UserDetails> {
private final UserDetailsService userDetailsService;
@Autowired
public AuditorAwareImpl(UserDetailsService userDetailsService){
this.userDetailsService = userDetailsService;
}
@Override
public UserDetails getCurrentAuditor() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return userDetailsService.loadUserByUsername(authentication.getName());
}
}
This works great for most operations, with the exception of the asynchronous tasks performed by the Spring batch SimpleAsyncTaskExecutor
.
By the time the entities require persistence, since it is SecurityContextHolder
destroyed after the request has been processed and jobLauncher.run(...)
asynchrno returns , the method AuditorAwareImpl.getCurrentAuditor()
throws a away NullPointerException
due to null getAuthentication()
:
java.lang.NullPointerException: null
at com.example.services.AuditorAwareImpl.getCurrentAuditor(AuditorAwareImpl.java:31)
at com.example.services.AuditorAwareImpl.getCurrentAuditor(AuditorAwareImpl.java:18)
So far, I've included the user calling the request as a non-identifying parameter in Job, but I don't know where it comes from.
How is it recommended to use Spring's built-in auditing when SecurityContextHolder
it is not suitable for finding the calling "auditor"?
source to share
You can wrap AsyncTaskExecutor
in DelegatingSecurityContextAsyncTaskExecutor
that specifically designed for Spring distribution SecurityContext
. Additionally, you will need to set MODE_INHERITABLETHREADLOCAL
for the security context.
source to share