Currently, My AuditorAware Implementation uses Spring's SecurityContextHolder to retrieve the current Auditor for saving creation/modification usernames:
@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 fine for most operations except for asynchronous tasks executed by Spring batch's SimpleAsyncTaskExecutor.
By the time entities need saving, since the SecurityContextHolder is wiped after the request has been processed, and the jobLauncher.run(...) returns asynchrnously, the AuditorAwareImpl.getCurrentAuditor() method throws a NullPointerException due to a 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 have included the request-invoking user as a non-identifying parameter to the Job but don't know where to proceed from here.
What is a recommended way of leveraging spring's inbuilt auditing when the SecurityContextHolder is not appropriate for finding the invoking "auditor"?