Skip to content

Commit

Permalink
Sikre api med azureAd
Browse files Browse the repository at this point in the history
Co-authored-by: Giao The Cung <giaothe@gmail.com>
  • Loading branch information
MariusEriksen and gtcno committed May 22, 2024
1 parent b27bb67 commit ff966b6
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 6 deletions.
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ dependencies {
testImplementation(libs.kotest.assertions.core)
testImplementation("io.ktor:ktor-server-test-host-jvm:${libs.versions.ktor.get()}")
testImplementation(libs.bundles.postgres.test)
testImplementation(libs.mock.oauth2.server)
}

application {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package no.nav.dagpenger.oppslag.journalpost.id

import mu.KotlinLogging
import no.nav.dagpenger.oppslag.journalpost.id.PostgresDataSourceBuilder.runMigration
import no.nav.dagpenger.oppslag.journalpost.id.api.journalpostApi
import no.nav.helse.rapids_rivers.RapidApplication
import no.nav.helse.rapids_rivers.RapidsConnection

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package no.nav.dagpenger.oppslag.journalpost.id
package no.nav.dagpenger.oppslag.journalpost.id.api

import io.ktor.server.application.Application
import io.ktor.server.application.install
import io.ktor.server.auth.Authentication
import io.ktor.server.plugins.callloging.CallLogging
import io.ktor.server.request.document
import mu.KotlinLogging
Expand All @@ -19,4 +20,8 @@ fun Application.apiConfig() {
).contains(call.request.document())
}
}

install(Authentication) {
jwt("azureAd")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package no.nav.dagpenger.oppslag.journalpost.id.api

import io.ktor.server.auth.AuthenticationConfig
import io.ktor.server.auth.jwt.JWTPrincipal
import io.ktor.server.auth.jwt.jwt

fun AuthenticationConfig.jwt(name: String) {
jwt(name) {
verifier(AzureAd)
validate { jwtClaims ->
JWTPrincipal(jwtClaims.payload)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
package no.nav.dagpenger.oppslag.journalpost.id
package no.nav.dagpenger.oppslag.journalpost.id.api

import io.ktor.http.HttpStatusCode
import io.ktor.server.application.Application
import io.ktor.server.application.ApplicationCall
import io.ktor.server.application.call
import io.ktor.server.auth.authenticate
import io.ktor.server.response.respond
import io.ktor.server.routing.get
import io.ktor.server.routing.route
import io.ktor.server.routing.routing
import no.nav.dagpenger.oppslag.journalpost.id.JournalpostRepository
import java.util.UUID

fun Application.journalpostApi(journalpostRepository: JournalpostRepository) {
apiConfig()

routing {
route("v1/journalpost/{søknadId}") {
get {
call.respond(HttpStatusCode.OK, journalpostRepository.hent(call.søknadId()))
authenticate("azureAd") {
route("v1/journalpost/{søknadId}") {
get {
call.respond(HttpStatusCode.OK, journalpostRepository.hent(call.søknadId()))
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package no.nav.dagpenger.oppslag.journalpost.id.api

import com.auth0.jwk.JwkProviderBuilder
import io.ktor.server.auth.jwt.JWTAuthenticationProvider
import java.net.URL

fun JWTAuthenticationProvider.Config.verifier(type: NaisJWTProviders) {
type.createVerifier(this)
}

abstract class NaisJWTProviders private constructor(
private val jwksUri: URL,
private val issuer: String,
private val clientId: String,
) {
constructor(jwksUri: String, issuer: String, clientId: String) : this(
jwksUri = URL(getEnvOrSystem(jwksUri)),
issuer = getEnvOrSystem(issuer),
clientId = getEnvOrSystem(clientId),
)

fun createVerifier(config: JWTAuthenticationProvider.Config) {
config.verifier(
JwkProviderBuilder(jwksUri).build(),
issuer,
) { this.withAudience(clientId) }
}
}

private fun getEnvOrSystem(name: String) = System.getenv(name) ?: System.getProperty(name)

object AzureAd : NaisJWTProviders("AZURE_OPENID_CONFIG_JWKS_URI", "AZURE_OPENID_CONFIG_ISSUER", "AZURE_APP_CLIENT_ID")
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@ package no.nav.dagpenger.oppslag.journalpost.id

import io.kotest.matchers.shouldBe
import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.client.statement.bodyAsText
import io.ktor.http.HttpHeaders
import io.ktor.http.HttpStatusCode
import io.ktor.server.testing.ApplicationTestBuilder
import io.ktor.server.testing.testApplication
import io.mockk.mockk
import no.nav.dagpenger.oppslag.journalpost.id.api.journalpostApi
import org.junit.jupiter.api.Test
import java.util.UUID.randomUUID

class JournalpostIdApiTest {
val mockAzure = MockAzure()

@Test
fun `Skal kunne finne journalpost id fra søknad id`() {
val journalpostId = "123"
Expand All @@ -20,12 +25,25 @@ class JournalpostIdApiTest {
it.lagre(søknadId, journalpostId)
}
withOppgaveApi(journalpostRepository = repository) {
client.get("v1/journalpost/$søknadId").let { response ->
client.get("v1/journalpost/$søknadId") {
header(HttpHeaders.Authorization, "Bearer ${mockAzure.lagToken()}")
}.let { response ->
response.status shouldBe HttpStatusCode.OK
response.bodyAsText() shouldBe journalpostId
}
}
}

@Test
fun unauthorized() {
withOppgaveApi {
client.get("v1/journalpost/${randomUUID()}") {
header(HttpHeaders.Authorization, "Bearer tull")
}.let { response ->
response.status shouldBe HttpStatusCode.Unauthorized
}
}
}
}

private fun withOppgaveApi(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package no.nav.dagpenger.oppslag.journalpost.id

import no.nav.security.mock.oauth2.MockOAuth2Server

class MockAzure {
companion object {
private const val AZURE_APP_CLIENT_ID = "test_client_id"
private const val AZURE_OPENID_CONFIG_ISSUER = "test_issuer"
private val mockOAuth2Server: MockOAuth2Server by lazy {
MockOAuth2Server().also { server ->
server.start()
}
}
}

init {
System.setProperty("AZURE_APP_CLIENT_ID", AZURE_APP_CLIENT_ID)
System.setProperty("AZURE_OPENID_CONFIG_ISSUER", "${mockOAuth2Server.issuerUrl(AZURE_OPENID_CONFIG_ISSUER)}")
System.setProperty("AZURE_OPENID_CONFIG_JWKS_URI", "${mockOAuth2Server.jwksUrl(AZURE_OPENID_CONFIG_ISSUER)}")
}

fun lagToken(): String {
return mockOAuth2Server.issueToken(
audience = AZURE_APP_CLIENT_ID,
issuerId = AZURE_OPENID_CONFIG_ISSUER,
).serialize()
}
}

0 comments on commit ff966b6

Please sign in to comment.