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

Ivan Brko

05/02/2020, 5:52 AM
Hi all, I am playing with Ktor and I can't get the routes (for custom features I'm implementing) in right order, I would be grateful for any help or links to more informations about how route pipelines are merged. Basically I am using built-in authentication and I want to add my own authorization. This is how I'm testing it in the routing code:
Copy code
authenticate{
  minimalRoleAllowed(Role.Admin) { //this is the call to my custom feature for authorization
    get{
      ...
    }
  }
}
So what I would expect here to happen is have authentication called, and then if it passes have authorization called. But it seems, somehow, that when all the pipelines are merged authorization gets called before authentication, which is of course wrong, because I can't authorize the user if I they are not authenticated. This is the implementation for my
minimalRouteAllowed
extension method:
Copy code
fun Route.minimalRoleAllowed(role: Role, build: Route.() -> Unit): Route {
    val authorisedRoute = createChild(AuthorisedRouteSelector()) //AuthorisedRouteSelector just returns a selector which evaluates to RouteSelectorEvaluation.Const

    application.feature(RoleAuthorization).interceptPipeline(authorisedRoute, role)

    authorisedRoute.build()
    return authorisedRoute
}
And this is how I'm inserting phase and intercepting in the
RoleAuthorization.interceptPipeline
called above (the
pipeline
here is
authorizedRoute
I sent in method above):
Copy code
pipeline.insertPhaseAfter(ApplicationCallPipeline.Features, authorizationPhase)
pipeline.intercept(authorizationPhase) {...
So, after some digging in the code, I found that what happens is that the parent role (one containing Authentication) is built and its phases are set after Features, and when we merge it with authorization pipeline, authorization also gets set after Features, which places it right after Features, but before Authentication. The workaround I found was to place authorization before Call, instead of after Features. But this seems buggy in different ways. What if later on in the route (so in the child of Authorization route) I call something else which adds phases after features? In that case that phase would again be added before my Authorization, even though hierarchically Authorization is higher up in the tree? How are these things handles usually?