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

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

问题描述

我使用Spring异步调用方法,使用@Async.这个方法调用了其他用@PreAuthorize注解的方法,Spring Security Annotation.为了使授权有效,我必须将 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.

作为一种可能的解决方案,您可以尝试子类化 ThreadPoolTask​​Executor 并覆盖其方法以手动传播 SecurityContext,然后声明该执行程序而不是 ;,类似这样:

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天全站免登陆