gpt4 book ai didi

java - Spring @Scheduled 方法 SecurityContext

转载 作者:行者123 更新时间:2023-12-05 07:07:37 26 4
gpt4 key购买 nike

@Scheduled 注释方法是否在任何 SecurityContext 之外?当我尝试使用以下内容时,它始终将 securitycontext/auth 设为 null。如果这不可能,那么运行用户特定身份验证感知计划任务的正确方法是什么?

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

最佳答案

给定的摘录永远行不通。

解释:

native session 管理由底层 servlet API 和容器提供。 HttpSession 对象仅在用户使用 request.getSession() 登录时创建,稍后此 HttpSession 将由 SecurityContextHolder.getContext().getAuthentication(); 内部。这意味着它与用户的请求有关,这是一个容器管理的线程,而不是您的调度程序将在其上运行的普通旧 JVM 线程。

这里你的调度器对用户没有任何依赖,它将在 JVM 管理的线程上独立运行。因此根本不会创建 HttpRequest/HttpSession 对象。

想象一下,当您第一次启动应用程序时,还没有用户登录,那么这里会是什么情况。

因此,您将始终只将 securitycontext/auth 设为 null。

回答你的问题

If this is not possible then what could be the right way to run userspecific authentication aware scheduled task?

我现在能想到的一种方法是,使用spring提供的SessionRegistry。它跟踪所有当前登录的用户。

因此,您可以通过 Autowiring 到此调度程序来传递此 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 session ,然后在您的安全配置中配置注册表。

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

有关如何获取当前登录用户的更多详细信息 see here .

关于java - Spring @Scheduled 方法 SecurityContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62069695/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com