为什么 SecurityContextHolder.getContext().authentication 在 Kotlin 异步方法中变为等于 null?

Why SecurityContextHolder.getContext().authentication becomes equal null inside the Kotlin async method?

我是 Kotlin 协程的新手,我想以异步方式为我的每个员工调用 API。但是我遇到了新协程旁边的问题,我无法从 SecurityContextHolder.getContext 检索身份验证。

谁能解释一下为什么 SecurityContextHolder.getContext().authentication 在 Kotlin 的 GlobalScope.async{...} 块内变得等于 null?新协程是否有单独的安全上下文?我该如何解决这个问题?我有办法避免将身份验证从调用 perform() 函数传递到 callApi() 函数吗?

您可以在下面找到代码片段:

fun perform() {
    // SecurityContextHolder.getContext().authentication contains some value!!!

    val deferred = employeesRepository.getEmployees().map { callApi(it) }

    runBlocking {
        deferred.forEach { it.await() }
    }

}

fun callApi(employee: EmployeeModel) = GlobalScope.async {
    // SecurityContextHolder.getContext().authentication is null here!!!
}

如果我没记错的话,SecurityContextHolder.getContext() 持有对身份验证对象的线程本地引用。使用协程你实际上切换到另一个线程(没有线程本地身份验证对象)。

我认为传递身份验证对象是可行的,这也是我开始阅读您的问题时的第一个想法。为什么要避免这种情况?

也许您可以使用 auth 对象创建一个协程上下文(或者是否有一个现有的用于此目的的上下文?),但这只是我的猜测,我还没有真正的协程经验。

编辑: 通过快速搜索,我找到了这个。您可以在此线程中找到有趣的想法: https://github.com/Kotlin/kotlinx.coroutines/issues/119