cpe
09/20/2022, 10:13 AMrouting {
get("/test") {
call.respondText("test called")
}
authenticate("auth-jwt") {
route("/featureA") {
get("/") {
val principalSubject = call.principal<JWTPrincipal>()?.subject
featureAService.handleGet(call, principalSubject)
}
post("/") {
val principalSubject = call.principal<JWTPrincipal>()?.subject
featureAService.handlePost(call, principalSubject)
}
put("/") {
val principalSubject = call.principal<JWTPrincipal>()?.subject
featureAService.handlePut(call, principalSubject)
}
}
route("/featureB") {
get("/") {
val principalSubject = call.principal<JWTPrincipal>()?.subject
featureBService.handleGet(call, principalSubject)
}
}
}
}
In this case I’d like to provide the principalSubject to each method (in reality there are a few more context parameters that are shared across those methods like parameters etc.). I don’t want to start each method with retrieving unsers and other context parameters and I also don’t want to repeat those lines in the routing section. Is there any way to reduce the amount of code here by having some preprocessor (could then use context-receivers)?August Lilleaas
09/20/2022, 10:21 AMAugust Lilleaas
09/20/2022, 10:23 AMfun myWrapper(
handler: suspend PipelineContext<Unit, ApplicationCall>.(
principalSubject: String?
) -> Unit
): PipelineInterceptor<Unit, ApplicationCall> {
return {
val principalSubject = call.principal<JWTPrincipal>()?.subject
this.handler(principalSubject)
}
}August Lilleaas
09/20/2022, 10:24 AMget("/foo", myWrapper { principal ->
featureAService.handleFoo(call, principal)
})Rustam Siniukov
09/20/2022, 10:27 AMcpe
09/20/2022, 10:36 AMRustam Siniukov
09/20/2022, 10:56 AMval plugin = createRouteScopedPlugin("myPlugin") {
on(AuthenticationChecked) { call ->
val data = call.principal.extractData()
call.attributes.put(MyKey, data)
}
}Rustam Siniukov
09/20/2022, 10:59 AMval ApplicationCall.myAuthData
get() = attributes.get(MyKey)simon.vergauwen
09/20/2022, 10:59 AMservice.auth { token -> }, and you can easily switch out implementations in testing as well.August Lilleaas
09/20/2022, 10:59 AMcall.principal<JWTPrincipal>()?.subjectAugust Lilleaas
09/20/2022, 10:59 AMsimon.vergauwen
09/20/2022, 11:00 AMAugust Lilleaas
09/20/2022, 11:03 AM!! for that oneAugust Lilleaas
09/20/2022, 11:03 AMsimon.vergauwen
09/20/2022, 11:05 AM!! anywhere, the errors it throws are much too vague to debug on Grafana. Additionally, I found it confusing to distinct in this way between required -and optional authentication.
Given the small size in which you can wrap Ktor to provide a more meaningful domain DSL is totally worth it for me.simon.vergauwen
09/20/2022, 11:06 AMsuspend while verifying the JWT tokens, which is not supported in the default authentication validator IIRC.cpe
09/20/2022, 3:05 PMauthentication / principal is null. I installed the plugin in my module section within the embeddedServer. But when calling
call.principal<JWTPrincipal>()
is null (and there is no principal.extractData() function).
When I receive the call within my routing configuration it is set properly and contains a JWTPrincipal.cpe
09/20/2022, 4:02 PM