https://kotlinlang.org logo
#ktor
Title
# ktor
d

Dominik Sandjaja

01/16/2023, 3:22 PM
I have a question regarding ktor plugins and the
on(AuthenticationChecked)
hook. I have a plugin that does role based authorization, simplified like this:
Copy code
val rbacPlugin = createRouteScopedPlugin(...) {
  pluginConfig.apply {
    on(AuthenticationChecked) { call ->
      println("Executing rbac plugin")
      if(call.principal<OurPrincipal>().role in roles) return
      throw ...
    }
  }
}
It is installed in a route like this:
Copy code
application.routing {
  route("somewhere") {
    authenticate(jwt) {
      install(rbacPlugin) { roles = setOf(...) }
      get { ... }
}}}
Nothing fancy and it works. Now I want to create another plugin, also hooking into the same phase:
Copy code
val SentryContextEnricher = createRouteScopedPlugin(name = "SentryContextEnricher") {
    on(AuthenticationChecked) { call ->
        println("Executing SentryContextEnricher plugin")
        val principal = call.principal<OurPrincipal>()
        if (principal != null) {
            val user = User().apply {
                id = principal.userId.id.toString()
            }
            Sentry.setUser(user)
        }
    }
}
The problem is that this latter plugin is always called before the authentication actually happens:
Copy code
Executing SentryContextEnricher plugin
Validated credentials & created JWT based principal
Executing rbac plugin
Is there anything that I am missing? Is there a limitation to the number of plugins that can be installed for a specific hook/phase?
r

Rustam Siniukov

01/16/2023, 3:32 PM
Do you install second plugin into
Route
or
Application
?
d

Dominik Sandjaja

01/16/2023, 3:32 PM
It is installed top-level in the application. (I also tried making it an
applicationScopedPlugin
with the same result)
r

Rustam Siniukov

01/16/2023, 3:37 PM
That’s the problem.
Application
pipeline is executed before any route matches, so there is no
authenticate {...}
block associated with the call and therefore to authentication
you can install your plugin in the top level route, it should fix the issue
d

Dominik Sandjaja

01/16/2023, 3:43 PM
Oh, wow, switching to
Copy code
routing {
    install(SentryContextEnricher)
}
does do the trick. Thank you very much! My follow-up question would be: Is there actually an application pipeline phase where the
on(AuthenticationChecked)
makes sense?
r

Rustam Siniukov

01/16/2023, 3:57 PM
Unfortunately not. Whole routing happens in a single phase of application pipeline. So there is nothing in between of authentication and calling route handler from the application perspective
d

Dominik Sandjaja

01/16/2023, 8:45 PM
Thank you for the responses! I will try to remember all this new knowledge when I run into the next issue 😄
28 Views