Spring Security 具有CompletableFuture的安全上下文为空

qkf9rpyu  于 2022-12-04  发布在  Spring
关注(0)|答案(1)|浏览(152)

我有一个奇怪的问题。
给定以下代码:

@RequestMapping(value = {"/randomizer"}, method = RequestMethod.POST)
    public CompletableFuture<String> randomizer(){
        CompletableFuture<String> someString = stringService
                .findRandomByInput("123")
                .thenCombine(stringService.findAnotherRandomByInput("321"), (result1, result2) -> {
                    return applyRandom(result1, result2);
                });

        CompletableFuture<Void> computation = computingService.computeRandomByInput(RandomDto.empty(), "123");

        return someString.thenCombineAsync(computation, (result1, result2) -> {
            combineIt(result1, result2, getCurrentApplicationUser());
        }, taskExecutor);
    }

通过调用getCurrentApplicationUser(),我可以访问Spring的SecurityContextHolder.getContext().getAuthentication()接口。
我有此任务执行者:

@Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(6);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("DmpkApplication-");
        executor.initialize();
        // the following is necessary because of:
        // https://stackoverflow.com/a/57434013/7320372
        return new DelegatingSecurityContextAsyncTaskExecutor(executor);
    }

所以问题是:
我调用上面的randomizer控制器5次,到第6次时,getAuthentication()调用是null
有时,对控制器的第一次调用会产生null,而所有其他后续调用都能正常工作。
我不知道这有什么问题。

smdncfj3

smdncfj31#

我自己找到了一个解决办法。
我重命名了上面的bean
public Executor taskExecutor()
以下内容:
public Executor executor()
现在问题解决了。我认为Spring本身已经定义了一个executor。之前的taskExecutor是一个附加的。但是不知何故,Spring的executor被调用了,默认情况下它不是DelegatingSecurityContextAsyncTaskExecutor
所以也许这就是问题所在。
没关系-现在它起作用了!

相关问题