Home > front end >  Change a value from a JWT token header with Ktor pipeline
Change a value from a JWT token header with Ktor pipeline

Time:01-06

I have a big problem. I'm on a project, where the client requires the jwt to be encrypted. So the company came up with a method that encrypts and decrypts a string as follows.

String.crypto() : String

String.decrypto(): String

When the user successfully logs in, a token is generated, for example:

 asdf.asdf.asdf (this token does not exist, it's just an example of a 3-part token)

and is then encrypted to

asdfghhjkl;asdsffgghhasfsfgg

accessing the login controller there is the following logic

post("/sign_in") { 
  val user = call.request<UserModel>()
  val login = service.login(user)
  if login != null
  val token = service.createToken()
  call.respond(200, token.encrypt() )
  else 
  call.respond(401)
}

In this way an encryption token is sent by the request.

When I'm receiving an encrypted token, I can't use it, because I need to decrypt it first.

I need to create a pipeline before the token is validated. I'm trying as follows:

fun Application.configureJWT() {
  install(JWTPlugin)
}

private val JWTPlugin = createApplicationPlugin("JWTPlugin") {
  onCall { call ->
    val jwtEncrypted: String? = call.request.headers["Authorization"]
    val jwtDecrypted: String? = jwtEncrypted?.replace("Bearer", "")?.trim()?.decrypt()?.getOrThrow()
    jwtDecrypted?.let { call.response.headers.append("Authorization", "Bearer $it") }
  }
}

I can't use

call.principal<JWTPrincipal>()

because the passed jwt is encrypted (asdfghhjkl;asdsffgghhasfsfgg) and does not follow the 3-part pattern

header. payload.signature

and when the JWT class tries to validate it it will throw an exception

com.auth0.jwt.exceptions.JWTDecodeException: The token was expected to have 3 parts, but got 1.

So my question is this: What's missing in my pipeline, after decrypting the jwt, following the next phases of the pipeline and being able to use the already decrypted jwt correctly?

CodePudding user response:

You can use the JWTAuthenticationProvider.Config.authHeader method to redefine the parsing of the Authorization header:

jwt("auth-jwt") {
    authHeader { call ->
        val header = call.request.headers[HttpHeaders.Authorization] ?: return@authHeader null
        // Decode here

        try {
            parseAuthorizationHeader(header)
        } catch (cause: IllegalArgumentException) {
            null
        }
    }
/// ...
}
  • Related