我想在我的应用程序中支持三种类型的请求:
Authorization
标头的请求。Authorization: Token {token}
标头的请求。我需要定义一个自定义机制来将令牌映射到 AuthUser。Authorization: Bearer {jwt}
标头的请求。每种类型的请求对应不同的速率限制:
在 Ktor 中实现此设置的最佳方法是什么?
我尝试使用
authenticate
来保护特定资源,但我遇到了 来宾访问 端点的问题。具体来说,当请求包含 Authorization
标头时,call.authentication.principal()
仍返回 null
。
或者,我可以对所有请求应用身份验证。但是,我不确定如何正确实施这种方法。
如何配置身份验证来处理所有请求类型(访客、自定义令牌、JWT)并为每种情况应用适当的速率限制?
authentication {
jwt {
authHeader { call ->
val header = call.request.headers["Authorization"]
if (header.isNullOrBlank()) {
return@authHeader HttpAuthHeader.Single("NoAuth", "")
}
if (header.startsWith("Bearer ")) {
return@authHeader HttpAuthHeader.Single("Bearer", header.removePrefix("Bearer "))
} else {
return@authHeader HttpAuthHeader.Single("Token", header.removePrefix("Bot "))
}
}
verifier { header ->
val scheme = header.authScheme
return@verifier when (scheme) {
"Bearer" -> Jwt.userVerifier
"Token" -> TODO("")
else -> TODO("")
}
}
validate {
println(it.payload.toString())
return@validate AuthUser(role = AuthUser.Role.NoLogin)
}
challenge { _, _ ->
call.respond(DataVo(401, "Unauthorized", null))
}
}
}
}
// reat limit
install(RateLimit) {
register {
requestKey { call ->
val headers = call.request.headers
headers["X-Real-IP"] ?: headers["X-Forwarded-For"] ?: call.request.origin.remoteHost
}
rateLimiter(limit = 6000, refillPeriod = 1.minutes)
requestWeight { call, _ ->
val user = call.principal<AuthUser>()
when {
// no header Authorization
user == null || !user.isLogin() -> 20
// Authorization: Token
user.isAdmin() -> 0
// Authorization: Bearer
else -> 8
}
}
}
}
据我所知,目前这是不可能的。 我已经在here提出了一个关于此问题的问题。