Spring Security 和 @Async(经过身份验证的用户混在一起)

标签 spring asynchronous spring-security

我使用 Spring 异步调用一个方法,使用 @Async .这个方法调用另一个用 @PreAuthorize 注释的方法。 ,Spring 安全注解。为了使授权工作,我必须设置 SecurityContextHolder模式为 MODE_INHERITABLETHREADLOCAL ,以便将身份验证信息传递给异步调用。到目前为止一切正常。

但是,当我注销并以其他用户身份登录时,SecurityContextHolder 在异步方法中存储已注销的旧用户的身份验证信息。它当然会导致不需要的 AccessDenied异常(exception)。同步调用不存在这样的问题。

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

最佳答案

我猜MODE_INHERITABLETHREADLOCAL不能与线程池一起正常工作。

作为一种可能的解决方案,您可以尝试继承 ThreadPoolTaskExecutor 并覆盖其传播方法SecurityContext手动,然后声明该执行程序而不是 <task:executor> ,类似这样:

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(经过身份验证的用户混在一起),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5246428/

相关文章:

spring - 错误的请求签名。 AWS ElasticSearch

java - Spring Security 注销不起作用 - 不清除安全上下文并且经过身份验证的用户仍然存在

java - 无法在 JPA 查询中进行投影

java - 在处理之前让 SpringBoot API 返回 200

javascript - 我如何解释 setTimeout 的这种行为?

javascript - 尝试了解如何在js中使用Promise

java - 尝试使用 Spring LDAP 进行编码

java - 即使定义了请求映射,为什么请求调度程序仍在 spring mvc 中查找 View ?

java - spring http-basic

java - 使用 Spring Security 配置 Spring Boot 会使构建因引用缺少依赖项而失败