Как я могу аутентифицировать пользователя системы для запланированных процессов в Spring?

у нас есть пакетное задание Quartz/ Spring, которое для целей ведения журнала аудита мы хотели бы, чтобы он был "аутентифицирован" как пользователь системы. Некоторые из наших методов полагаются на получение SecurityContext для этого. Способы запуска этого задания доверяют (или аутентифицируются). Мы не хотим использовать пароль или другой токен (так как процесс в основном всегда генерируется кварцем).

Я пробовал это

private void authenticate() {
    UserDetails admin = userDetailsService.loadUserByUsername( "admin" );

    RunAsUserToken token = new RunAsUserToken(
            UUID.randomUUID().toString(), admin, admin.getAuthorities(), null , null );

    Authentication user = authenticationManager.authenticate( token );

    if ( user.isAuthenticated() ) {
        SecurityContext sc = new SecurityContextImpl();
        sc.setAuthentication( user );
        SecurityContextHolder.setContext( sc );
    }
}

но это привело к

org.springframework.security.authentication.ProviderNotFoundException: No AuthenticationProvider found for org.springframework.security.access.intercept.RunAsUserToken

и я не уверен, что некоторые параметры RunAsUserToken (например, ключ) или что я должен давать в отношении учетных данных.

Как я могу аутентифицировать или иным образом устанавливать контекст безопасности, как если бы он был аутентифицирован как этот пользователь?

Ответ 1

Я еще не уверен в RunAsUserToken. Я думаю, что он предназначен для использования, когда кто-то уже прошел проверку подлинности, но приложение, что выполнить что-то в качестве другого пользователя.

Я нашел пример использования здесь.

Но, может быть, вам это действительно не нужно. Если это так, вы можете просто сделать:

Authentication auth = new UsernamePasswordAuthenticationToken(admin.getUsername(), admin.getPassword(), admin.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(auth);

И тогда администратор будет аутентифицирован. Кроме того, вам не нужно использовать admin.getPassword(), поскольку он не будет проверен в любом случае.

Обратите внимание, что вам не нужно создавать контекст безопасности: он уже существует. По-моему, по умолчанию это ThreadLocal.