Kotlin Ktor提示从基本身份验证块内的路由拦截器中输入凭据

Kotlin Ktor提示从基本身份验证块内的路由拦截器中输入凭据,kotlin,basic-authentication,ktor,Kotlin,Basic Authentication,Ktor,当我设置一个基本身份验证提供程序并将一个简单的get处理程序放在一个authenticate块中时,当我尝试访问路由时,会提示我输入凭据,因此一旦get处理程序开始执行,我就可以访问UserIdPrincipal并开始查找与帐户相关的数据。但是,我现在想扩展我的authenticate块以包括多个路由,因此我认为我可以在一个intercept块内处理主体/帐户的初始处理。但是,当我尝试这样做时,不会提示我输入凭据,因此拦截器中的UserIdPrincipal为null。如何让Ktor在身份验证块

当我设置一个基本身份验证提供程序并将一个简单的get处理程序放在一个authenticate块中时,当我尝试访问路由时,会提示我输入凭据,因此一旦get处理程序开始执行,我就可以访问UserIdPrincipal并开始查找与帐户相关的数据。但是,我现在想扩展我的authenticate块以包括多个路由,因此我认为我可以在一个intercept块内处理主体/帐户的初始处理。但是,当我尝试这样做时,不会提示我输入凭据,因此拦截器中的UserIdPrincipal为null。如何让Ktor在身份验证块中的路由拦截器中提示我输入凭据

当我尝试访问仪表板路由时,此代码正确地提示我输入凭据

authenticate("teacherAuth") {
    get("dashboard") {
        val principal = call.principal<UserIdPrincipal>()!!
        val schoolName = principal.name
        val school = transaction {
            School.find { Schools.name eq schoolName }.singleOrNull()
        }
        if (school == null)
            call.respondText("No school \"$schoolName\" found")
        else
            call.respondHtml {
                ...
            }
    }
}
当我尝试访问仪表板路由时,此代码不会提示我输入凭据,从而导致错误

authenticate("teacherAuth") {
    val schoolKey = AttributeKey<School>("school")

    intercept(ApplicationCallPipeline.Setup) {
        val principal = call.principal<UserIdPrincipal>()!!
        val schoolName = principal.name
        val school = transaction {
            School.find { Schools.name eq schoolName }.singleOrNull()
        }
        if (school == null) {
            call.respondText("No school \"$schoolName\" found")
            return@intercept finish()
        }
        call.attributes.put(schoolKey, school)
    }

    get("dashboard") {
        val school = call.attributes[schoolKey]
        call.respondHtml {
            ...
        }
    }
}

将侦听器阶段设置为ApplicationCallPipeline.Call修复了该问题,现在提示我输入凭据。这一想法归功于@f-caron。

可能是您在错误的阶段拦截。身份验证通常处于功能阶段。您正在身份验证之前的安装阶段进行侦听。谢谢,将侦听器阶段设置为ApplicationCallPipeline。Call修复了此问题。