Use Keycloak-Realm-Roles for authorization
This commit is contained in:
1 parent
f8b4215233
commit
c4400a0334
4 files changed
+64
-15
No files matched your search
@@ -0,0 +1,33 @@
|
|||||||
|
package books
|
||||||
|
|
||||||
|
import books.model.BookRepository
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.server.auth.*
|
||||||
|
import io.ktor.server.response.*
|
||||||
|
import io.ktor.server.routing.*
|
||||||
|
import net.keinekekse.app.UserRoles
|
||||||
|
import org.koin.ktor.ext.inject
|
||||||
|
|
||||||
|
fun Route.booksRoute() {
|
||||||
|
val repository: BookRepository by inject<BookRepository>()
|
||||||
|
|
||||||
|
authenticate(UserRoles.BOOKS_USER.roleName) {
|
||||||
|
route("/books") {
|
||||||
|
get("/books") {
|
||||||
|
// call.respondText("Test DB route")
|
||||||
|
val books = repository.allBooks()
|
||||||
|
call.respond(books)
|
||||||
|
}
|
||||||
|
get("/book/{id}") {
|
||||||
|
// TODO safe toInt conv
|
||||||
|
val id = call.parameters["id"]!!.toInt()
|
||||||
|
repository.bookById(id)?.let { call.respond(it) }
|
||||||
|
?: call.respondText(
|
||||||
|
"Book with id $id not found",
|
||||||
|
status = HttpStatusCode.NotFound
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
package net.keinekekse.app.server.config
|
package net.keinekekse.app.server.config
|
||||||
|
|
||||||
|
import books.booksRoute
|
||||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
import io.ktor.server.auth.*
|
import io.ktor.server.auth.*
|
||||||
import io.ktor.server.response.*
|
import io.ktor.server.response.*
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
|
import net.keinekekse.app.UserRoles
|
||||||
import net.keinekekse.app.server.VERSION
|
import net.keinekekse.app.server.VERSION
|
||||||
import net.keinekekse.app.server.testdb.testDbRoute
|
|
||||||
|
|
||||||
private val logger = KotlinLogging.logger {}
|
private val logger = KotlinLogging.logger {}
|
||||||
|
|
||||||
fun Application.configureRouting() {
|
fun Application.configureRouting() {
|
||||||
routing {
|
routing {
|
||||||
authenticate("auth-KC") {
|
authenticate(UserRoles.BOOKS_USER.roleName) {
|
||||||
get("/") {
|
get("/") {
|
||||||
val principal = call.principal<AppPrincipal>()
|
val principal = call.principal<AppPrincipal>()
|
||||||
call.respondText("user: ${principal?.userId}")
|
call.respondText("user: ${principal?.userId}")
|
||||||
@@ -24,6 +25,6 @@ fun Application.configureRouting() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
testDbRoute()
|
booksRoute()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ import io.ktor.server.application.*
|
|||||||
import io.ktor.server.auth.*
|
import io.ktor.server.auth.*
|
||||||
import io.ktor.server.auth.jwt.*
|
import io.ktor.server.auth.jwt.*
|
||||||
import io.ktor.server.response.*
|
import io.ktor.server.response.*
|
||||||
|
import net.keinekekse.app.UserRoles
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
private val logger = KotlinLogging.logger {}
|
private val logger = KotlinLogging.logger {}
|
||||||
@@ -25,18 +26,23 @@ fun Application.configureSecurity() {
|
|||||||
val issuer = "$keycloakUrl/$keycloakRealm"
|
val issuer = "$keycloakUrl/$keycloakRealm"
|
||||||
|
|
||||||
authentication {
|
authentication {
|
||||||
jwt("auth-KC") {
|
for (role in UserRoles.entries) {
|
||||||
verifier(
|
jwt(role.roleName) {
|
||||||
UrlJwkProvider(URI(certUrl).toURL()), issuer
|
verifier(
|
||||||
) {
|
UrlJwkProvider(URI(certUrl).toURL()), issuer
|
||||||
withAudience("account")
|
) {
|
||||||
withClaim("azp", keycloakClientId)
|
withAudience("account")
|
||||||
}
|
withClaim("azp", keycloakClientId)
|
||||||
challenge { _, _ ->
|
}
|
||||||
call.respond(HttpStatusCode.Unauthorized, "Token is not valid or has expired")
|
challenge { _, _ ->
|
||||||
}
|
call.respond(HttpStatusCode.Unauthorized, "Token is not valid or has expired")
|
||||||
validate { credential ->
|
}
|
||||||
AppPrincipal(credential)
|
validate { credential ->
|
||||||
|
val principal = AppPrincipal(credential)
|
||||||
|
if (principal.roles.contains(role.roleName) ||
|
||||||
|
principal.roles.contains(UserRoles.ADMIN.roleName)
|
||||||
|
) principal else null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package net.keinekekse.app
|
||||||
|
|
||||||
|
enum class UserRoles(val roleName: String) {
|
||||||
|
ADMIN("admin"),
|
||||||
|
BOOKS_ADMIN("books-admin"),
|
||||||
|
BOOKS_USER("books-user"),
|
||||||
|
BOOKS_EDITOR("books-editor")
|
||||||
|
|
||||||
|
}
|
||||||
Reference in new issue
Block a user