qohatpp
09/18/2024, 5:35 PMfun Route.withRestrictions(build: Route.() -> Unit): Route {
val authorizedRoute = createChild(AuthenticationRouteSelector(listOf(PermissionPlugin)))
authorizedRoute.install(PermissionPlugin)
authorizedRoute.build()
return authorizedRoute
}
So I can do something like.
route("/path") {
withRestrictions {
....
}
}
I would like to get a header from the request and return it in the extension function build block, I've tried something like
fun Route.withRestrictions(build: Route.(String) -> Unit): Route {
val authorizedRoute = createChild(AuthenticationRouteSelector(listOf(PermissionPlugin)))
authorizedRoute.install(PermissionPlugin)
authorizedRoute.intercept(Plugins or Call) {
val myHeader = call.request.headers["request"]
if(myHeader == null) {
call.respond(BadRequest, "The header is not present")
finish()
return@intercept
}
authorizedRoute.build(myHeader)
}
return authorizedRoute
}
So I could use the header value in my route logic like this.
route("/path") {
withRestrictions { myHeader ->
....
}
}
Actually I've spend time on this and not been able to solve it... the example above didn't work, any idea how can I solve this?Aleksei Tirman [JB]
09/19/2024, 8:48 AMwithRestrictions
is a route builder executed once when the server starts but the headers are sent on each request. So either withRestrictions
can have children routes or it can handle the request.Renan Kummer
09/19/2024, 6:30 PM@Suppress("functionName")
fun JwtAuthorize(vararg requiredRoles: RoleName = emptyArray()) = createRouteScopedPlugin("JwtAuthorize") {
on(AuthenticationChecked) { call ->
val principal = call.principal<JWTPrincipal>()
if (principal != null) {
val userRoles = principal.getClaim("userRoles", Array<String>::class) ?: emptyArray()
if (requiredRoles.any { role -> !userRoles.contains(role.value) }) {
throw UnauthorizedException()
}
}
}
}
And my authorization extension function:
fun Route.authorize(vararg roles: RoleName = emptyArray(), handler: Route.() -> Unit) {
authenticate {
install(JwtAuthorize(*roles)) { handler() }
}
}
This way I can simply add authorize(the-role-required) { <route mapping here> }
and it validates authentication and RBAC authorization for the routes mapped.Renan Kummer
09/19/2024, 6:32 PMRenan Kummer
09/19/2024, 6:35 PMcall
object prior to being handled by the router