Spring Security和@Async(经过身份验证的用户混在一起) [英] Spring Security and @Async (Authenticated Users mixed up)

查看:501
本文介绍了Spring Security和@Async(经过身份验证的用户混在一起)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用@Async与Spring异步调用该方法.该方法调用其他以Spring Security Annotation @PreAuthorize注释的方法.为了使授权有效,我必须将SecurityContextHolder模式设置为MODE_INHERITABLETHREADLOCAL,以便将身份验证信息传递到异步调用.到目前为止一切正常.

I asynchronously invoke method with Spring, using @Async.This method invokes other method annotated with @PreAuthorize, Spring Security Annotation. To make authorization works I have to set SecurityContextHolder mode to MODE_INHERITABLETHREADLOCAL, so that authentication info is passed to the asynchronous call. Everything works fine so far.

但是,当我注销并以其他用户身份登录时,在SecurityContextHolder异步方法中,存储了已注销的旧用户的身份验证信息.当然,这会导致不必要的AccessDenied异常.同步调用没有这种问题.

However when I logout and login as a different user, in asynchronous method SecurityContextHolder stores authentication info of the old user, that has bee logged out. It causes of course unwanted AccessDenied exception. There is no such problem with synchronous calls.

我已经定义了<task:executor id="executors" pool-size="10"/>,所以一旦执行程序池中的线程被初始化后就不会覆盖身份验证信息,这可能是一个问题吗?

I have defined <task:executor id="executors" pool-size="10"/>, so may it be a problem that once thread in executors pool has been initialized it will not override authentication information?

推荐答案

我想MODE_INHERITABLETHREADLOCAL在线程池中无法正常工作.

I guess MODE_INHERITABLETHREADLOCAL doesn't work correctly with thread pool.

作为一种可能的解决方案,您可以尝试将

As a possible solution you can try to subclass ThreadPoolTaskExecutor and override its methods to propagate SecurityContext manually, and then declare that executor instead of <task:executor>, something like this:

public void execute(final Runnable r) {
    final Authentication a = SecurityContextHolder.getContext().getAuthentication();

    super.execute(new Runnable() {
        public void run() {
            try {
                SecurityContext ctx = SecurityContextHolder.createEmptyContext();
                ctx.setAuthentication(a);
                SecurityContextHolder.setContext(ctx);
                r.run();
            } finally {
                SecurityContextHolder.clearContext();
            }
        }
    });
}

这篇关于Spring Security和@Async(经过身份验证的用户混在一起)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆