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"?

+3


source to share


1 answer


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.



+3


source







All Articles