我正在基于用户角色的身份验证。我的interceptors
的执行顺序错误:用户角色,身份验证。需要切换它们,以便我可以访问UserTypeAuthentication中经过身份验证的用户Principal
。当我调试代码时,拦截器以正确的顺序注册。管道似乎也处于正确的顺序。
class UserTypeAuthentication{
class Configuration
companion object Feature : ApplicationFeature<Application, Configuration, UserTypeAuthentication> {
val userRestrict = PipelinePhase("UserTypeAuth")
override val key = AttributeKey<UserTypeAuthentication>("UserTypeAuth")
override fun install(pipeline: Application, configure: Configuration.() -> Unit): UserTypeAuthentication {
return UserTypeAuthentication().apply { configure(configure) }
}
}
fun interceptPipeline(
pipeline: ApplicationCallPipeline,
vararg types: JWTUserType
) {
pipeline.insertPhaseAfter(ApplicationCallPipeline.Features, userRestrict)
pipeline.intercept(userRestrict){
val user = call.authentication.principal as AuthenticatedUser
if (!types.contains(user.type)) {
call.respond(HttpStatusCode.Unauthorized)
finish()
}
}
}
private fun configure(configure: Configuration.() -> Unit) {}
}
fun Route.only(
vararg types : JWTUserType,
build: Route.() -> Unit
): Route {
val authenticatedRoute = createChild(
UserTypeRoute(types.toList().distinct().map { it.toString() })
)
application.feature(UserTypeAuthentication).interceptPipeline(authenticatedRoute, *types)
authenticatedRoute.build()
return authenticatedRoute
}
@Test
fun testMultipleConfigurationsNested() = withTestApplication {
application.install(CustomHeader)
application.install(Authentication) {
basic {
validate {
when(it.name){
"customer" -> AuthenticatedUser(1, JWTUserType.CUSTOMER)
"admin" -> AuthenticatedUser(2, JWTUserType.ADMIN)
else -> null
}
}
}
}
application.install(UserTypeAuthentication)
application.routing {
authenticate {
only(JWTUserType.CUSTOMER){
route("/route") { handle { call.respondText("OK") } }
}
}
}
handleRequest(HttpMethod.Post, "/route") {
addHeader(
HttpHeaders.Authorization,
HttpAuthHeader.Single("basic", Base64.getEncoder().encodeToString("customer:password".toByteArray())).render()
)
}.let { call ->
assertEquals(HttpStatusCode.OK.value, call.response.status()?.value)
}
handleRequest(HttpMethod.Post, "/route") {
addHeader(
HttpHeaders.Authorization,
HttpAuthHeader.Single("basic", Base64.getEncoder().encodeToString("admin:password".toByteArray())).render()
)
}.let { call ->
assertEquals(HttpStatusCode.Unauthorized.value, call.response.status()?.value)
}
}
谢谢您的任何想法:)
编辑:
我发现,如果我以前使用过,则该测试有效。因为authenticatedRoute
应该始终插入Features
和Call
之间,所以使用之前和之后有什么区别吗?
//pipeline.insertPhaseAfter(ApplicationCallPipeline.Features,authenticatedRoute)
pipeline.insertPhaseBefore(ApplicationCallPipeline.Call, authenticatedRoute)