Last active
August 16, 2024 06:46
-
-
Save Shreemanarjun/bfe4ffb6664bdcd4514ab53e9007f299 to your computer and use it in GitHub Desktop.
Revisions
-
Shreemanarjun revised this gist
Aug 14, 2024 . 1 changed file with 1 addition and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -82,6 +82,7 @@ val RoleBasedAuthorizationPlugin = createRouteScopedPlugin( val definedRoles = pluginConfig.authorityConfigs.map { it.userRole } pluginConfig.apply { //After the JWT Token Verified do check on roles and access levels on(AuthenticationChecked) { call -> /// get the token role from claim val tokenRule = call.getRoleFromToken() -
Shreemanarjun created this gist
Aug 14, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,181 @@ package example.com.plugins import io.ktor.http.* import io.ktor.server.application.* import io.ktor.server.auth.* import io.ktor.server.auth.jwt.* import io.ktor.server.request.* import io.ktor.server.response.* routing { authenticate("authJWT") { authorized( //Define the user role and its acces levels for authority authorityWithAccessLevels = setOf( AuthorityWithAccessLevel( UserRole.PATIENT, accessLevels = setOf(AccessLevel.Read), ) ), build = { patientRoute() }) } } ///authorization plugin for Route fun Route.authorized( authorityWithAccessLevels: Set<AuthorityWithAccessLevel>, build: Route.() -> Unit, ) { install(RoleBasedAuthorizationPlugin) { authorityConfigs = authorityWithAccessLevels build() } } @Serializable enum class UserRole { //Patient PATIENT, //Doctor DOCTOR, //Pharmacy PHARMACY, //Diagnostic Center DIAGNOSTICS, //Admin ADMIN, } /** * User With Access Levels * * */ enum class AccessLevel { Read, Write, Delete, Update } data class AuthorityWithAccessLevel(var userRole: UserRole, var accessLevels: Set<AccessLevel> = emptySet()) class PluginConfiguration { var authorityConfigs: Set<AuthorityWithAccessLevel> = emptySet() } val RoleBasedAuthorizationPlugin = createRouteScopedPlugin( name = "Role Based Authentication Plugin", createConfiguration = ::PluginConfiguration ) { ///get the user defined roles here val definedRoles = pluginConfig.authorityConfigs.map { it.userRole } pluginConfig.apply { on(AuthenticationChecked) { call -> /// get the token role from claim val tokenRule = call.getRoleFromToken() println("token rule: $tokenRule") if (tokenRule != null) { /// Check whether current user token have the required role val authorized = definedRoles.contains(tokenRule) println("authorized token: $authorized") when { !authorized -> { call.respond( status = HttpStatusCode.Forbidden, MyResult.Error( exception = "Invalid Role", message = "User doesn't have permission to authenticate! ${ call.request.uri }", reasons = listOf("${definedRoles.joinToString()} role not found") ) ) } //User have authorized according to role defined else -> { //get all the requested access levels of user val currentRequestedAccessLevels = call.getAuthorityAccess() //get all the aceess levels defined in the route val authorizedaccessLevels = pluginConfig.authorityConfigs.find { it.userRole == tokenRule }?.accessLevels if (!authorizedaccessLevels!!.containsAll(currentRequestedAccessLevels)) { call.respond( status = HttpStatusCode.Forbidden, MyResult.Error( exception = "User $tokenRule doesn't have permission to ${currentRequestedAccessLevels.joinToString()}", message = "User doesn't have permission to authenticate! ${ call.request.uri }", reasons = listOf("${currentRequestedAccessLevels.joinToString()} access not found") ) ) } } } } else { call.respond( status = HttpStatusCode.BadRequest, MyResult.Error( exception = "Invalid Role", message = "Check Header", reasons = listOf("$definedRoles role not found ") ) ) } } } } fun ApplicationCall.getAuthorityAccess(): Set<AccessLevel> { val currentAccessLevel = mutableSetOf<AccessLevel>() when (this.request.httpMethod) { HttpMethod.Get, HttpMethod.Head -> { currentAccessLevel.add(AccessLevel.Read) } HttpMethod.Put -> { currentAccessLevel.add(AccessLevel.Write) } HttpMethod.Delete -> { currentAccessLevel.add(AccessLevel.Delete) } HttpMethod.Patch, HttpMethod.Post -> { currentAccessLevel.add(AccessLevel.Update) } } return currentAccessLevel } fun ApplicationCall.getRoleFromToken(): UserRole? { val role = this.principal<JWTPrincipal>()?.payload?.getClaim("role")?.asString() if (role != null) { println("role in claim $role") println("getRoleFromToken: ${UserRole.valueOf(role)}") return UserRole.valueOf(role) } return null }