Authentication with Auth0 is working on development but my tests are all failing with a 401 now. I have tried to mock it but get the provided error below. I feel like this is a very common problem that any tested API application would have to overcome so thought I would reach out to any Kotlin or Java devs that might know a way to solve this:
For example, this spec should pass, its Kotest with Mockk:
it("returns an empty list") {
withService() {
val response = client.get("/v1/users") {
headers.append("Content-Type", "application/json")
headers.append("Authorization", "Bearer ${token}")
}
response.status shouldBe HttpStatusCode.OK
response.bodyAsText().shouldBe("""{"data":[]}""")
}
}
Here is an example of Route setup:
fun Application.configureRouting() {
install(Authentication) {
jwt("auth0") {
verifier(JwtValidator.jwkProvider, System.getProperty("AUTH_0_DOMAIN"))
validate { credential -> JwtValidator.validateCreds(credential) }
}
}
routing {
route("/v1") {
userRouting()
}
}
}
fun Route.userRouting() {
authenticate("auth0") {
route("/users") {
get {
val users = transaction { User.all().map { it.to_json() } }
call.respond(mapOf("data" to users))
}
}
}
}
I have tried to mock it but it's turned into mock city.
it("returns an empty list") {
setTestEnvVariables()
val jwkProvider = mockk<JwkProvider>()
val jwk = mockk<Jwk>()
val publicKey: RSAPublicKey = generateTestKeyPair().public as RSAPublicKey
// Create a non-relaxed mock for the JWTVerifier
val verifier = mockk<JWTVerifier>()
val decodedJwt = mockk<DecodedJWT>()
mockkObject(JwtValidator) // Mock the JwtValidator object
// Mock the behavior of JwtValidator.jwkProvider
every { JwtValidator.jwkProvider } returns jwkProvider
// Mock the behavior of JwtValidator.validateCreds
every { JwtValidator.validateCreds(any()) } returns JWTPrincipal(mockk())
// Mock the behavior of JwkProvider.get
every { jwkProvider.get(any()) } returns jwk
// Mock the behavior of Jwk.getAlgorithm
every { jwk.getAlgorithm() } returns "RS256"
// Mock the behavior of Jwk.getPublicKey
every { jwk.publicKey } returns publicKey
// Return the mocked DecodedJWT on successful verification
every { verifier.verify(authorizationToken) } returns decodedJwt
withService() {
val response = client.get("/v1/users") {
headers.append("Content-Type", "application/json")
headers.append("Authorization", "Bearer ${token}")
}
response.status shouldBe HttpStatusCode.OK
response.bodyAsText().shouldBe("""{"data":[]}""")
}
}
Here is the error it gets with a mocked test
2023-07-20 08:47:17.407 [DefaultDispatcher-worker-1] TRACE io.ktor.auth.jwt - Token verification failed
com.auth0.jwt.exceptions.SignatureVerificationException: The Token's Signature resulted invalid when verified using the Algorithm: SHA256withRSA
at com.auth0.jwt.algorithms.RSAAlgorithm.verify(RSAAlgorithm.java:51)
at com.auth0.jwt.JWTVerifier.verify(JWTVerifier.java:463)
at com.auth0.jwt.JWTVerifier.verify(JWTVerifier.java:445)
2023-07-20 08:47:17.408 [DefaultDispatcher-worker-1] TRACE io.ktor.se