Объект аутентификации не был найден в SecurityContext при срабатывании @Scheduled? - PullRequest
0 голосов
/ 19 октября 2019

Я создал приложение Spring Boot, и у меня возникли проблемы с некоторыми конечными точками, которые можно активировать вручную или с помощью аннотации @Scheduled.

Проблема, которую я получаю, является следующей:

org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: в SecurityContext не найден объект аутентификации

. Есть ли способ вызвать SecurityContext, если процесс вызван через @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
    }
}

Ответы [ 2 ]

2 голосов
/ 19 октября 2019

Метод @Scheduled не должен быть @Secured. Запланированные методы уже находятся в доверенном коде.

Выполните рефакторинг вашего кода, например,

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

    @Autowired
    private MyService myService;

    @PostMapping(path="/run")
    public void runJobs() {
        myService.runJobs();
    }
}
@Service
public class MyService {

    @Scheduled(cron = "* * * * * *")
    public void runJobs() {
        // Do some operations
    }
}
1 голос
/ 19 октября 2019

В основном вы должны настроить свой планировщик с необходимой аутентификацией. Что-то в строках следующего:

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);
    }
}

Тогда вы можете аннотировать свой контроллер с помощью @Secured("hasAuthority('ADMIN')").

...