如何为 Spring 中的计划进程验证系统用户?

How can I authenticate a system user for scheduled processes in Spring?

我们有一个 Quartz/Spring 批处理作业,出于审计日志记录的目的,我们希望它 "authenticated" 作为系统用户。我们的一些方法依赖于获取 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 参数的作用(例如密钥)或关于凭据我应该给它什么。

如何进行身份验证或以其他方式设置安全上下文,就好像它已作为该用户进行了身份验证一样?

我还不确定 RunAsUserToken。我认为它的目的是在某人已经通过身份验证时使用,但应用程序以另一个用户的身份执行某些操作。

I found an example of using it here.

但是,也许您并不真的需要它。如果是这样,您可以这样做:

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

然后管理员将通过身份验证。此外,您不需要使用 admin.getPassword(),因为它不会被检查。

请注意,您不必创建安全上下文:它已经存在。我认为默认是ThreadLocal