Skip to content

Commit

Permalink
Endrer maskinporten oauth provider så den er likere de andre
Browse files Browse the repository at this point in the history
Co-authored-by: Robin Tordly <[email protected]>
Co-authored-by: Sturle Helland <[email protected]>
Co-authored-by: Vetle Hollund <[email protected]>
  • Loading branch information
4 people committed Feb 7, 2024
1 parent 0febb34 commit 3b0991d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.http.ContentType.Application.FormUrlEncoded
import io.ktor.serialization.jackson.*
import java.time.Instant

const val GRANT_TYPE = "urn:ietf:params:oauth:grant-type:jwt-bearer"
const val LEEWAY_SECONDS: Long = 20
Expand All @@ -22,20 +21,13 @@ interface Oauth2JwtProvider {

class HttpClientMaskinportenTokenProvider(
private val config: MaskinportenConfig,
private val client: HttpClient = defaultHttpClient
) : Oauth2JwtProvider {
private val grants: JwtGrantFactory = JwtGrantFactory(config)
private val cache = mutableMapOf<String, Token>()
private val client = HttpClient(CIO) {
install(ContentNegotiation) {
jackson {
registerModule(JavaTimeModule())
disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
}
}
}
private val cache = TokenCache()

override suspend fun getToken(): String {
val token = cache[config.scope]?.takeUnless(Token::hasExpired) ?: fetchToken()
val token = cache.get(config.scope)?.takeUnless(Token::hasExpired) ?: fetchToken()
return token.access_token.let(SignedJWT::parse).parsedString
}

Expand All @@ -44,13 +36,17 @@ class HttpClientMaskinportenTokenProvider(
contentType(FormUrlEncoded)
setBody("grant_type=$GRANT_TYPE&assertion=${grants.jwt}")
}.body<Token>().also { token ->
cache[config.scope] = token
cache.add(config.scope, token)
}

private data class Token(val access_token: String) {
private val signedJwt = SignedJWT.parse(access_token)
private val expiry = signedJwt.jwtClaimsSet.expirationTime.toInstant().minusSeconds(LEEWAY_SECONDS)

fun hasExpired() = expiry < Instant.now()
private companion object {
private val defaultHttpClient = HttpClient(CIO) {
install(ContentNegotiation) {
jackson {
registerModule(JavaTimeModule())
disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package no.nav.aap.ktor.client.maskinporten.client

import com.nimbusds.jwt.SignedJWT
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import org.slf4j.Logger
import java.time.Instant

internal data class Token(val access_token: String) {
private val signedJwt = SignedJWT.parse(access_token)
private val expiry = signedJwt.jwtClaimsSet.expirationTime.toInstant().minusSeconds(LEEWAY_SECONDS)

fun hasExpired() = expiry < Instant.now()
}

internal class TokenCache {
private val tokens: HashMap<String, Token> = hashMapOf()
private val mutex = Mutex()

internal fun logg(logger: Logger) {
tokens.forEach { (key, value) ->
logger.info("Key: $key, Value: $value")
}
}

internal suspend fun add(key: String, token: Token) {
mutex.withLock {
tokens[key] = token
}
}

internal suspend fun get(key: String): Token? {
mutex.withLock {
tokens[key]
}?.let {
if (it.hasExpired()) {
rm(key)
}
}

return mutex.withLock {
tokens[key]
}
}

private suspend fun rm(key: String) {
mutex.withLock {
tokens.remove(key)
}
}
}

0 comments on commit 3b0991d

Please sign in to comment.