首页 > 解决方案 > 为什么 auth0 的 Java JWT 库无法接受自定义声明的 Object/Any?

问题描述

我正在尝试基于对象创建自定义 JWT 声明。我认为这应该是可行的,因为 auth0.jwt 使用 jackson-databind。这是一个简单的例子:

                data class Foo(val strings: List<String>)

                val bar = Foo(listOf("hello", "world"))

                val jwtAlgorithm = Algorithm.RSA256(
                    loadPublicKeyFromFile("testPublicKey.pem"),
                    loadPrivateKeyFromFile("testPrivateKey_pkcs8.pem")
                )

                val payload = mapOf("customClaim" to bar)
                val token = JWT.create().withPayload(payload).sign(jwtAlgorithm)

但是,我得到以下异常

java.lang.IllegalArgumentException: Claim values must only be of types Map, List, Boolean, Integer, Long, Double, String and Date

我注意到在反序列化自定义声明时,我需要将 Jackson 注释(例如 @JsonCreator 和 @JsonProperty)添加到我的声明模型类中,而我自己在使用 Jackson 时不需要这些注释。

我的项目正在使用以下相关库:

            "com.auth0:java-jwt:3.18.1",
            "com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_version", 
            "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version",
            "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:$jackson_version"

其中jackson_version = 2.9.7

这里发生了什么,有没有比编写代码将我的自定义声明对象转换为地图更好的方法来修复它?

标签: kotlinjwtauth0jackson-databind

解决方案


我认为这是因为 SDK 尝试通过执行诸如确保所有值都不为 null 之类的操作来验证有效负载,它们通过将您可以使用的类型限制为它们已实现验证的类型来实现这一点。

自述文件中提到了这一点(尽管他们似乎忘记提及Map是允许的):

当前支持的自定义 JWT 声明创建和验证类包括:布尔、整数、双精度、字符串、日期以及字符串和整数类型的数组。

所以是的,如果您想使用 SDK,您将需要转换为地图。或者不要使用 SDK——我个人已经分叉了他们的 SDK,以解决它不支持刷新管理 API 令牌和遵守速率限制的问题。我怀疑从长远来看,编写自己的 Auth0 API 客户端可能会更容易。


推荐阅读