【问题标题】:How do I get access to errors in custom Ktor JWT challenge?如何访问自定义 Ktor JWT 挑战中的错误?
【发布时间】:2020-10-04 05:26:44
【问题描述】:

我希望能够对不同的 JWTAuth 错误做出不同的响应,因此自定义了挑战(以下是我一直用来测试的一些代码)。不幸的是,上下文为错误返回了一个空列表。我已经用过期的令牌进行了测试,根本没有令牌。

fun JWTAuthenticationProvider.Configuration.customConfigure() {
    verifier(verifier)
    realm = ISSUER
    challenge { _, _ ->
      call.respond(HttpStatusCode.Unauthorized, JSONObject(mapOf("err" to context.authentication.allErrors)))
    }
    validate { 
      if (it.payload.audience.contains(AUDIENCE)) {
        it.payload.getClaim("id").asString().let { id -> userDao.getUserById(id) }
      } else null
    }
  }

我想知道我是否遗漏了什么。希望有人能帮忙!

【问题讨论】:

  • 我也不知道。我所做的是手动检查错误是什么,并在没有 JWT 配置功能的情况下相应地发送。
  • @NeelKamath 我也不介意这样做。有没有什么地方可以看到你是怎么做到的?我使用的是statuspages,但我所能做的就是无缘无故地捕获错误,因此无法给出不同的响应。
  • 我的代码相当做作,我可能误解了你的问题。但我所做的是让我自己的身份验证功能。我还没有在JWTAuthenticationProvider.Configuration 上创建扩展方法。每个需要身份验证的端点的第一行调用此函数,如果需要,throws 相关的Exception
  • @NeelKamath 啊,我明白了。我已经在 Node 后端编写了自己的身份验证,所以也许我会在 Ktor 中做同样的事情。谢谢你的建议:)

标签: kotlin jwt-auth ktor


【解决方案1】:

尝试使用验证块,您可以使用有效负载检查错误并使用状态页面功能通过抛出异常来响应

【讨论】:

    【解决方案2】:

    也许不是最优雅的解决方案,但它可以满足我的需要,所以现在没问题。我使用自定义质询根据错误抛出带有特定错误消息的异常。

    fun JWTAuthenticationProvider.Configuration.customConfigure() {
        verifier(verifier)
        realm = ISSUER
        challenge { _, _ ->
          // get custom error message if error exists
          val errorMessage = call.request.headers["Authorization"]?.let {
            if (it.isNotEmpty()) {
              try {
                val jwt = it.replace("Bearer ", "")
                verifier.verify(jwt)
                ""
              } catch (e: Exception) {
                when (e) {
                  is JWTVerificationException ->
                    if (e.localizedMessage.contains("expired")) "Token expired" else "Invalid token"
                  else -> "Unknown token error"
                }
              }
            } else "Authorization token empty"
          } ?: "No authorization header"
          // if error throw UnauthorizedException
          if (errorMessage.isNotEmpty()) {
            throw UnauthorizedException(errorMessage)
          }
        }
        validate {
          if (it.payload.audience.contains(AUDIENCE)) {
            it.payload.getClaim("id").asString().let { id -> userDao.getUserById(id) }
          } else null
        }
      }
    

    然后按照建议,我使用状态页面功能进行响应。

    // catch authorization exception
    exception<UnauthorizedException> {
          call.respond(HttpStatusCode.Unauthorized, JSONObject(mapOf("err" to it.message)))
        }
    

    【讨论】:

    • verifier.verify() 在这个解决方案中会被调用两次吗?一次在 Ktor 的代码中,一次在这个挑战函数中?
    • 是的,不幸的是它会。我不再使用 Ktor 的 JWT 身份验证,因为我无法解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 2021-11-12
    相关资源
    最近更新 更多