72 lines
2.4 KiB
Kotlin
72 lines
2.4 KiB
Kotlin
package com.restapi.config
|
|
|
|
import com.fasterxml.jackson.module.kotlin.readValue
|
|
import com.restapi.config.AppConfig.Companion.appConfig
|
|
import com.restapi.domain.Session
|
|
import com.restapi.domain.Session.objectMapper
|
|
import io.javalin.http.Context
|
|
import io.javalin.http.HandlerType
|
|
import io.javalin.http.UnauthorizedResponse
|
|
import org.jose4j.jwk.HttpsJwks
|
|
import org.jose4j.jwt.consumer.ErrorCodes
|
|
import org.jose4j.jwt.consumer.InvalidJwtException
|
|
import org.jose4j.jwt.consumer.JwtConsumerBuilder
|
|
import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver
|
|
import org.slf4j.LoggerFactory
|
|
import java.net.URI
|
|
import java.net.http.HttpClient
|
|
import java.net.http.HttpRequest
|
|
import java.net.http.HttpResponse
|
|
import java.util.concurrent.ConcurrentHashMap
|
|
import java.util.function.Function
|
|
|
|
object Auth {
|
|
|
|
|
|
private val authCache = ConcurrentHashMap<String, AuthEndpoint>()
|
|
|
|
fun getAuthEndpoint(): AuthEndpoint {
|
|
return authCache.computeIfAbsent("AUTH") {
|
|
val wellKnown =
|
|
"${appConfig.iamUrl()}/realms/${appConfig.iamRealm()}/.well-known/openid-configuration"
|
|
val client = HttpClient.newHttpClient()
|
|
|
|
val req = HttpRequest.newBuilder()
|
|
.uri(URI.create(wellKnown))
|
|
.GET().build()
|
|
|
|
objectMapper.readValue<AuthEndpoint>(
|
|
client.send(req, HttpResponse.BodyHandlers.ofString()).body()
|
|
)
|
|
}
|
|
|
|
}
|
|
|
|
private val jwtConsumer = JwtConsumerBuilder()
|
|
.setRequireExpirationTime()
|
|
.setAllowedClockSkewInSeconds(30)
|
|
.setRequireSubject()
|
|
.setExpectedIssuer(getAuthEndpoint().issuer)
|
|
.setExpectedAudience("account")
|
|
.setVerificationKeyResolver(HttpsJwksVerificationKeyResolver(HttpsJwks(getAuthEndpoint().jwksUri)))
|
|
.build()
|
|
|
|
|
|
fun parseAuthToken(authToken: String): AuthUser {
|
|
|
|
// Validate the JWT and process it to the Claims
|
|
val jwtClaims = jwtConsumer.process(authToken)
|
|
val userId = jwtClaims.jwtClaims.claimsMap["preferred_username"] as String
|
|
val tenant = jwtClaims.jwtClaims.claimsMap["tenant"] as String
|
|
val roles = ((jwtClaims.jwtClaims.claimsMap["realm_access"] as Map<String, Any>)["roles"]) as List<String>
|
|
|
|
return AuthUser(
|
|
userName = userId,
|
|
tenant = tenant,
|
|
roles = roles
|
|
)
|
|
}
|
|
|
|
}
|
|
|
|
data class AuthUser(val userName: String, val tenant: String, val roles: List<String>) |