如何访问自定义 Ktor JWT 挑战中的错误?

Posted

技术标签:

【中文标题】如何访问自定义 Ktor JWT 挑战中的错误?【英文标题】:How do I get access to errors in custom Ktor JWT challenge? 【发布时间】: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 中做同样的事情。谢谢你的建议:) 【参考方案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 身份验证,因为我无法解决这个问题。

以上是关于如何访问自定义 Ktor JWT 挑战中的错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止用户使用 JWT 创建自定义 POST 请求?

如何记录并响应来自 Ktor 中 JWT 授权失败的错误消息?

JWT:如何在密码或用户名错误 Django REST 上实现我的自定义错误消息

BeetleX.FastHttpApi之JWT和自定义访问验证

如何覆盖 logRequest/logResponse 以在 Ktor 客户端日志记录中记录自定义消息?

NestJS:如何在从 JWT AuthGuard 扩展的 GraphQL 自定义 Guard 中从请求中获取用户