Spring @Scheduled метод SecurityContext - PullRequest
1 голос
/ 28 мая 2020

Является ли @Scheduled аннотированным методом из любого SecurityContext? Когда я пытаюсь использовать следующее, он всегда имеет securitycontext/auth как null. Если это невозможно, то каким может быть правильный способ запуска заданной пользователем c запланированной задачи с поддержкой аутентификации?

    @Scheduled(fixedDelay = 10000)
    // This method will send notifications to the current user
    public void sendUserNotifications() {
        SecurityContext sc = SecurityContextHolder.getContext();
        Authentication auth = sc.getAuthentication();

        if(auth == null) {

            log.info(">> SecurityContext=[{}], Authentication[auth] is {}, please login to receive notifications", sc, auth);

            return;
        }

1 Ответ

0 голосов
/ 30 мая 2020

Данный отрывок никогда не сработает.

Объяснение:

Собственное управление сеансом обеспечивается базовым API сервлета и контейнером. Объект HttpSession создается только тогда, когда пользователь входит в систему, используя request.getSession() под капотом, а позже этот HttpSession будет использоваться SecurityContextHolder.getContext().getAuthentication(); внутри. Это означает, что он связан с запросом пользователя, который представляет собой управляемый контейнером поток, а не простой старый поток JVM, на котором будет работать ваш планировщик.

Здесь ваш планировщик имеет какую-либо зависимость от пользователя, он будет работать независимо от потока, управляемого JVM. Таким образом, объект HttpRequest/HttpSession не будет создан вообще.

Представьте себе самый первый раз, когда вы запускаете приложение, и ни один пользователь еще не вошел в систему, тогда каков будет сценарий здесь.

Таким образом, вы всегда будете получать securitycontext/auth только как null.

Чтобы ответить на ваш вопрос

Если это невозможно, то каким может быть правильный способ запуска заданной пользователем c запланированной задачи с учетом аутентификации?

Один из способов, о котором я могу думать прямо сейчас, - это использование пружины SessionRegistry. Он отслеживает всех вошедших в систему пользователей.

Таким образом, вы можете передать этот объект SessionRegistry, автоматически подключившись к этому планировщику, получить список всех основных / вошедших в систему пользователей и отправить им уведомление.

Примерно так, как показано ниже -

    @EnableScheduling
    @Component
    public class MyScheduler { 

    @Autowired
    @Qualifier("sessionRegistry")
    private SessionRegistry sessionRegistry;
    @Scheduled(fixedDelay = 10000)
    // This method will send notifications to the current user
    public void sendUserNotifications() {
    List<UserDetails> principals = sessionRegistry.getAllPrincipals()
        .stream()
        .filter(principal -> principal instanceof UserDetails)
        .map(UserDetails.class::cast)
        .collect(Collectors.toList());

    // send notification to all users.      
   }

Кроме того, вы должны включить sessionRegistry в вашей конфигурации безопасности, сначала вы должны прослушивать сеансы HTTP, а затем настроить реестр в вашей конфигурации безопасности.

        public class AppInitializer implements WebApplicationInitializer {

        @Override
        public void onStartup(ServletContext servletContext) {
        ...
        servletContext.addListener(HttpSessionEventPublisher.class);
         }
        }

и конфигурация безопасности -

 @Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        // ...
        http.sessionManagement().maxSession(1).sessionRegistry(sessionRegistry());
    }

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }

    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }
 }

Подробнее о том, как получить текущих авторизованных пользователей , см. Здесь .

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...