val requestingUserAttribute = AttributeKey("requestingUser") /** * Intercepts the call pipeline after the auth stage and attaches a user to the incoming * call. */ fun Route.addUserAttributeInterceptor(userService: UserService) { // Typically we'd intercept the feature phase but in this case we want to intercept // after the authentication feature runs, which happens right before the call phase intercept(ApplicationCallPipeline.Call) { val principal = call.principal() ?: throw DataReferenceError("No claim found") val userID = principal.payload.getClaim(USER_ID_CLAIM_NAME).asInt() ?: throw DataReferenceError("Principal does not have user ID") // DataReferenceError is a custom error in my code that gets caught by status pages val user = userService.getUser(userID) ?: throw DataReferenceError("Could not find user $userID from claim.") // Now any routing block that calls addUserAttributeInterceptor can retrieve calling user from call.attributes[requestingUserAttribute] call.attributes.put(requestingUserAttribute, user) } }