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

时间:2019-10-22 09:02:01

标签: kotlin spring-security kotlin-coroutines

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

有人可以解释一下为什么Kotlin中SecurityContextHolder.getContext().authentication内的null等于GlobalScope.async{...}吗?新协程是否具有单独的安全上下文?我该如何解决这个问题?我有一种方法可以避免将身份验证从调用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!!!
}

1 个答案:

答案 0 :(得分:0)

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

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

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

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