Ktor 中如何动态选择使用哪种认证方式?
How to dynamically choose which authentication method is used in Ktor?
我在我的应用程序中实现了 google sign-in:
fun Application.module(testing: Boolean = false) {
install(CallLogging)
install(ContentNegotiation) {
gson {
setPrettyPrinting()
}
}
val jwtIssuer = environment.config.property("jwt.domain").getString()
val jwtAudience = environment.config.property("jwt.audience").getString()
val jwtRealm = environment.config.property("jwt.realm").getString()
val jwkProvider = JwkProviderBuilder(URL("https://www.googleapis.com/oauth2/v3/certs"))
.cached(10, 24, TimeUnit.HOURS)
.rateLimited(10, 1, TimeUnit.MINUTES)
.build()
install(Authentication) {
jwt {
verifier(jwkProvider) {
withIssuer(jwtIssuer)
withAudience(jwtAudience)
}
realm = jwtRealm
validate { credentials ->
if (credentials.payload.audience.contains(jwtAudience))
JWTPrincipal(credentials.payload)
else
null
}
}
}
routing {
authenticate {
post("/token-sign-in") {
val payload = call.principal<JWTPrincipal>()?.payload ?: error("JWTPrincipal not found")
call.respond(
UserWire(
id = payload.subject,
email = payload.getClaim("email").asString(),
name = payload.getClaim("name").asString(),
profilePictureUrl = payload.getClaim("picture").asString()
)
)
}
}
}
}
我想在用户每次访问其中一条路由时对用户进行身份验证,但我希望同时选择 google 和 firebase-auth 登录。问题是他们需要不同的方法来检查给定令牌的真实性,因此我需要两种身份验证方法。
我想在调用的 header 中包含一个 "AuthenticationProvider: "Google|Firebase"" ,我会根据它的值来决定应该调用哪种身份验证方法.
所以像这样:
fun Application.module(testing: Boolean = false) {
install(Authentication) {
jwt("google") {
// verify google sign in token
}
jwt("firebase") {
// verify firebase token
}
firebaseOrGoogle("firebaseOrGoogle") {
// check header value for auth provider
// verify token with either "firebase" or "google" auth methods
}
}
routing {
authenticate("firebaseOrGoogle") {
post("/token-sign-in") {
// ...
}
get("/transactions") {
// ...
}
}
}
}
这可能吗?
如果可行,请提供一些代码,说明如何动态决定应调用哪种身份验证方法?
作为替代解决方案,您可以配置身份验证功能以尝试通过这两种方法证明用户的身份。第一次成功的检查获胜。为此,只需将这两个配置名称传递给 authenticate
方法:
routing {
authenticate("google", "firebase") {
post("/token-sign-in") {
// ...
}
get("/transactions") {
// ...
}
}
}
参数的顺序决定了首先进行的检查。
我在我的应用程序中实现了 google sign-in:
fun Application.module(testing: Boolean = false) {
install(CallLogging)
install(ContentNegotiation) {
gson {
setPrettyPrinting()
}
}
val jwtIssuer = environment.config.property("jwt.domain").getString()
val jwtAudience = environment.config.property("jwt.audience").getString()
val jwtRealm = environment.config.property("jwt.realm").getString()
val jwkProvider = JwkProviderBuilder(URL("https://www.googleapis.com/oauth2/v3/certs"))
.cached(10, 24, TimeUnit.HOURS)
.rateLimited(10, 1, TimeUnit.MINUTES)
.build()
install(Authentication) {
jwt {
verifier(jwkProvider) {
withIssuer(jwtIssuer)
withAudience(jwtAudience)
}
realm = jwtRealm
validate { credentials ->
if (credentials.payload.audience.contains(jwtAudience))
JWTPrincipal(credentials.payload)
else
null
}
}
}
routing {
authenticate {
post("/token-sign-in") {
val payload = call.principal<JWTPrincipal>()?.payload ?: error("JWTPrincipal not found")
call.respond(
UserWire(
id = payload.subject,
email = payload.getClaim("email").asString(),
name = payload.getClaim("name").asString(),
profilePictureUrl = payload.getClaim("picture").asString()
)
)
}
}
}
}
我想在用户每次访问其中一条路由时对用户进行身份验证,但我希望同时选择 google 和 firebase-auth 登录。问题是他们需要不同的方法来检查给定令牌的真实性,因此我需要两种身份验证方法。
我想在调用的 header 中包含一个 "AuthenticationProvider: "Google|Firebase"" ,我会根据它的值来决定应该调用哪种身份验证方法.
所以像这样:
fun Application.module(testing: Boolean = false) {
install(Authentication) {
jwt("google") {
// verify google sign in token
}
jwt("firebase") {
// verify firebase token
}
firebaseOrGoogle("firebaseOrGoogle") {
// check header value for auth provider
// verify token with either "firebase" or "google" auth methods
}
}
routing {
authenticate("firebaseOrGoogle") {
post("/token-sign-in") {
// ...
}
get("/transactions") {
// ...
}
}
}
}
这可能吗? 如果可行,请提供一些代码,说明如何动态决定应调用哪种身份验证方法?
作为替代解决方案,您可以配置身份验证功能以尝试通过这两种方法证明用户的身份。第一次成功的检查获胜。为此,只需将这两个配置名称传递给 authenticate
方法:
routing {
authenticate("google", "firebase") {
post("/token-sign-in") {
// ...
}
get("/transactions") {
// ...
}
}
}
参数的顺序决定了首先进行的检查。