当 @Scheduled 触发时,在 SecurityContext 中未找到 Authentication 对象?

Dmy*_*kyi 1 java spring spring-security spring-scheduled spring-boot

我创建了一个Spring Boot应用程序,但在某些可以手动或通过@Scheduled注释触发的端点上遇到了问题。

我遇到的问题如下:

org.springframework.security.authentication.AuthenticationCredentialsNotFoundException:在SecurityContext中找不到身份验证对象

SecurityContext如果进程调用 via ,是否有办法触发@Scheduled

我是新手Spring Security,很难理解参考指南。我发现了一些类似的问题,但仍然无法理解如何将答案应用于我的案例。

我的例子MyController

@Secured("ROLE_ADMIN")
@RestController
@RequestMapping(value = "/api")
public class MyController {

    @Scheduled(cron = "* * * * * *")
    @GetMapping(path="/data")
    public void getData() {
        // Do some operations
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 5

基本上,您必须使用必要的身份验证来配置您的调度程序。大致如下:

import com.google.common.collect.ImmutableList;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.concurrent.DelegatingSecurityContextScheduledExecutorService;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;

import java.util.List;
import java.util.concurrent.Executor;

import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
import static org.springframework.security.core.context.SecurityContextHolder.getContext;

@Configuration
public class SchedulerConfiguration implements SchedulingConfigurer {

    private static final String KEY = "spring";
    private static final String PRINCIPAL = "spring";
    private static final List<SimpleGrantedAuthority> AUTHORITIES = ImmutableList.of(new SimpleGrantedAuthority("ADMIN"));

    @Override
    public void configureTasks(final ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }

    @Bean
    public Executor taskExecutor() {
        final AnonymousAuthenticationToken token = new AnonymousAuthenticationToken(KEY, PRINCIPAL, AUTHORITIES);
        final SecurityContext securityContext = getContext();
        securityContext.setAuthentication(token);
        return new DelegatingSecurityContextScheduledExecutorService(newSingleThreadScheduledExecutor(), securityContext);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以用 注释你的控制器@Secured("hasAuthority('ADMIN')")