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

为什么SecurityContextHolder.getContext().authentication在Kotlin异步方法中变为等于null?,kotlin,spring-security,kotlin-coroutines,Kotlin,Spring Security,Kotlin Coroutines,我是Kotlin协程的新手,我想以异步方式为我的每个员工调用API。但我面临的问题是,在新的协同程序中,我无法从SecurityContextHolder.getContext检索身份验证 有人能解释一下为什么Kotlin中的GlobalScope.async{…}块中的SecurityContextHolder.getContext().authentication变得相等null?新的协同程序是否有单独的安全上下文?我该如何解决这个问题?我有没有办法避免将身份验证从调用的perform()函

我是Kotlin协程的新手,我想以异步方式为我的每个员工调用API。但我面临的问题是,在新的协同程序中,我无法从
SecurityContextHolder.getContext
检索身份验证

有人能解释一下为什么Kotlin中的
GlobalScope.async{…}
块中的
SecurityContextHolder.getContext().authentication
变得相等
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对象创建一个协同路由上下文(或者是否有用于此目的的现有上下文?),但这只是我的猜测,我还没有实际的协同路由经验

编辑: 通过快速搜索,我找到了这个。您可以在该线程中找到有趣的想法: