Данный отрывок никогда не сработает.
Объяснение:
Собственное управление сеансом обеспечивается базовым 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();
}
}
Подробнее о том, как получить текущих авторизованных пользователей , см. Здесь .
Надеюсь, это поможет.