From cfecb894642a08b241dacf6d6682e1966a2ee25d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simen=20H=C3=B8ston?= Date: Tue, 24 Oct 2023 08:54:12 +0200 Subject: [PATCH] Oppretter egen resttemplate for maskinporten som legger til bearer automatisk --- .../maskinporten/MaskinportenClient.kt | 14 +++++++++- .../web/config/RestOperationsMaskinporten.kt | 21 +++++++++++++++ ...askinportenBearerTokenClientInterceptor.kt | 26 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/no/nav/bidrag/commons/web/config/RestOperationsMaskinporten.kt create mode 100644 src/main/kotlin/no/nav/bidrag/commons/web/interceptor/MaskinportenBearerTokenClientInterceptor.kt diff --git a/src/main/kotlin/no/nav/bidrag/commons/security/maskinporten/MaskinportenClient.kt b/src/main/kotlin/no/nav/bidrag/commons/security/maskinporten/MaskinportenClient.kt index 8f5c2ef..107f200 100644 --- a/src/main/kotlin/no/nav/bidrag/commons/security/maskinporten/MaskinportenClient.kt +++ b/src/main/kotlin/no/nav/bidrag/commons/security/maskinporten/MaskinportenClient.kt @@ -6,6 +6,7 @@ import com.fasterxml.jackson.module.kotlin.readValue import com.github.benmanes.caffeine.cache.Caffeine import com.github.benmanes.caffeine.cache.LoadingCache import com.nimbusds.jwt.SignedJWT +import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.stereotype.Service import java.net.URI import java.net.http.HttpClient @@ -33,7 +34,9 @@ import java.net.http.HttpResponse.BodyHandlers.ofString * maskinporten: * enabled: true */ -@Service + +@EnableConfigurationProperties(MaskinportenConfig::class) +@Service("maskinportenClient") class MaskinportenClient( private val maskinportenConfig: MaskinportenConfig ) { @@ -62,6 +65,15 @@ class MaskinportenClient( } } + fun hentMaskinportenToken(): SignedJWT { + val cache = maskinportenTokenCache.get(maskinportenConfig.scope) { nyttScope: String -> + MaskinportenTokenCache(hentNyttJwtToken(nyttScope)) + } ?: error("Feil ved henting eller opprettelse av cached scope for maskinporten-token! Scope: ${maskinportenConfig.scope}, cache content: $maskinportenTokenCache") + return cache.run { + maskinportenToken ?: renew(hentNyttJwtToken(maskinportenConfig.scope)) + } + } + private fun hentNyttJwtToken(scope: String): String = httpClient.send(opprettMaskinportenTokenRequest(scope), ofString()).run { if (statusCode() != 200) throw MaskinportenClientException("Feil ved henting av token: Status: ${statusCode()} , Body: ${body()}") diff --git a/src/main/kotlin/no/nav/bidrag/commons/web/config/RestOperationsMaskinporten.kt b/src/main/kotlin/no/nav/bidrag/commons/web/config/RestOperationsMaskinporten.kt new file mode 100644 index 0000000..908da7c --- /dev/null +++ b/src/main/kotlin/no/nav/bidrag/commons/web/config/RestOperationsMaskinporten.kt @@ -0,0 +1,21 @@ +package no.nav.bidrag.commons.web.config + +import no.nav.bidrag.commons.web.interceptor.MaskinportenBearerTokenClientInterceptor +import org.springframework.boot.web.client.RestTemplateBuilder +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Import +import org.springframework.context.annotation.Scope + +@Configuration +@Import(RestTemplateBuilderBean::class, + MaskinportenBearerTokenClientInterceptor::class) +class RestOperationsMaskinporten { + + @Bean("maskinporten") + @Scope("prototype") + fun restOperationsMaskinporten( + restTemplateBuilder: RestTemplateBuilder, + maskinportenBearerTokenClientInterceptor: MaskinportenBearerTokenClientInterceptor + ) = restTemplateBuilder.additionalInterceptors(maskinportenBearerTokenClientInterceptor).build() +} \ No newline at end of file diff --git a/src/main/kotlin/no/nav/bidrag/commons/web/interceptor/MaskinportenBearerTokenClientInterceptor.kt b/src/main/kotlin/no/nav/bidrag/commons/web/interceptor/MaskinportenBearerTokenClientInterceptor.kt new file mode 100644 index 0000000..3e06b3a --- /dev/null +++ b/src/main/kotlin/no/nav/bidrag/commons/web/interceptor/MaskinportenBearerTokenClientInterceptor.kt @@ -0,0 +1,26 @@ +package no.nav.bidrag.commons.web.interceptor + +import no.nav.bidrag.commons.security.maskinporten.MaskinportenClient +import org.springframework.context.annotation.Import +import org.springframework.http.HttpRequest +import org.springframework.http.MediaType +import org.springframework.http.client.ClientHttpRequestExecution +import org.springframework.http.client.ClientHttpRequestInterceptor +import org.springframework.http.client.ClientHttpResponse +import org.springframework.stereotype.Component + +@Component +@Import(MaskinportenClient::class) +class MaskinportenBearerTokenClientInterceptor(private val maskinportenClient: MaskinportenClient): ClientHttpRequestInterceptor { + + override fun intercept( + request: HttpRequest, + body: ByteArray, + execution: ClientHttpRequestExecution + ): ClientHttpResponse { + request.headers.setBearerAuth(maskinportenClient.hentMaskinportenToken().parsedString) + request.headers.accept = listOf(MediaType.APPLICATION_JSON) + request.headers.contentType = MediaType.APPLICATION_JSON + return execution.execute(request, body) + } +} \ No newline at end of file