Skip to content

Commit

Permalink
Extract KeyCloak roles from token directly
Browse files Browse the repository at this point in the history
  • Loading branch information
pklimai committed Dec 23, 2024
1 parent 0b508bf commit 2ffae3c
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 21 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ kotlin {
implementation("io.ktor:ktor-client-cio:$ktorVersion")
implementation("io.ktor:ktor-client-auth:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.github.developer--:JwtParser:1.0.0")
}
}

Expand Down
1 change: 1 addition & 0 deletions src/jvmMain/kotlin/Application.kt
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ fun Application.main() {
post("/${EVENT_ENTITY_API_NAME}") {

val roles = call.principal<WithRoles>()?.roles!!
// println("Roles in EVENT_ENTITY_API_NAME: $roles")
if (!(roles.isWriter or roles.isAdmin)) {
call.respond(HttpStatusCode.Unauthorized)
return@post
Expand Down
35 changes: 14 additions & 21 deletions src/jvmMain/kotlin/keycloak.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ru.mipt.npm.nica.ems

import JwtParser
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.engine.cio.*
Expand All @@ -13,6 +14,7 @@ import jakarta.ws.rs.NotAuthorizedException
import org.keycloak.admin.client.Keycloak
import org.keycloak.representations.AccessTokenResponse
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.jsonArray

@Serializable
data class KCUserInfo(
Expand Down Expand Up @@ -53,27 +55,16 @@ fun getKCtoken(config: ConfigFile, username: String, pass: String): String? {
}

suspend fun getKCgroups(config: ConfigFile, token: String): List<String> {
val client = HttpClient(CIO) {
install(ContentNegotiation) {
json()
}
install(Auth) {
bearer {
loadTokens {
BearerTokens(token, "")
}
}
}
val parser = JwtParser()
val jsonToken = parser.parseToJsonObject(token)
// println(jsonToken?.get("groups"))
val res = mutableListOf<String>()
jsonToken?.get("groups")?.jsonArray?.forEach {
// println(it)
res.add((it.toString().replace("/", "").replace("\"", "")))
}
var groupsObtained: List<String>?
val url =
"${config.keycloak_auth?.server_url}/realms/${config.keycloak_auth?.realm}/protocol/openid-connect/userinfo"
//runBlocking {
val response = client.get(url)
val res: KCUserInfo? = response.body()
groupsObtained = res?.groups
//}
return groupsObtained ?: listOf()
// println(res)
return res
}

suspend fun getKCPrincipalOrNull(config: ConfigFile, username: String, pass: String): Principal? {
Expand All @@ -83,9 +74,11 @@ suspend fun getKCPrincipalOrNull(config: ConfigFile, username: String, pass: Str
}

fun rolesFromGroups(config: ConfigFile, groups: List<String>): UserRoles {
return UserRoles(
val res = UserRoles(
isReader = true, // any authenticated user
isWriter = groups.contains(config.keycloak_auth?.writer_group_name), // e.g. "bmneventwriter", can add records
isAdmin = groups.contains(config.keycloak_auth?.admin_group_name) // e.g. "bmneventadmin", can delete records
)
// println("res = $res")
return res
}

0 comments on commit 2ffae3c

Please sign in to comment.