如何使用 JJWT 从有效负载中获取自定义字段

Jac*_*les 3 java claims jwt jjwt

好的,我在生成 JWT 时向有效负载添加了几个自定义声明,我可以在我的前端 (javascript) 中将它们拉出来就好了。然后我让我的 javascript 向一个微服务发送一个 ajax 调用,它连同它一起传递 JWT。我想从微服务中的 JWT 中获取我的自定义声明。我正在做以下事情:

Claims claims = Jwts.parser().setSigningKey(Vars.SECRET_KEY).parseClaimsJws(token).getBody();
 User user = claims.get("customuser", User.class);
Run Code Online (Sandbox Code Playgroud)

它抛出一个异常。

io.jsonwebtoken.RequiredTypeException: Expected value to be of type: class net.netdatacorp.netdauth.model.User, but was class java.util.LinkedHashMap
    at io.jsonwebtoken.impl.DefaultClaims.get(DefaultClaims.java:128)
Run Code Online (Sandbox Code Playgroud)

以下是我的自定义声明在前端 JWT 检查器中的数据显示方式。

{
  jti: "83bffbad-7d36-4370-9332-21a84f2a3dce",
  iat: 1498241526,
  sub: "test",
  iss: "www.test.net",
  customuser: {
    userId: 1,
    userCd: "TMM",
    firstNm: "Testy",
    lastNm: "McTesty",
    userNm: "test",
    emailAddress: "jacob@test.net",
    active: true,
    createdDt: 1491355712000,
    createdByUserId: 0,
    lastUpdateDt: 1498199278000,
    lastUpdateByUserId: 0,
    lastLoginDt: 1484928016000
  }
}
Run Code Online (Sandbox Code Playgroud)

我缺少什么才能拉出我的自定义声明?

Abh*_*eet 5

我们可以使用 Jackson 的对象映射器将 Claims(即 a Map<String, Object>)转换为我们的自定义声明 java 对象。

final ObjectMapper mapper = new ObjectMapper();

Claims jwsMap = Jwts.parser()
       .setSigningKey("SECRET")
       .parseClaimsJws("jwt")
       .getBody();
return mapper.convertValue(jwsMap, MyCustomClaim.class);
Run Code Online (Sandbox Code Playgroud)

还要添加该代码以尝试捕获以确保我们处理丢失/篡改签名的情况。

  • 请添加一些解释。 (2认同)

Jac*_*les 0

好的,所以我转而使用 Jose4J 而不是 JJWT,在努力让所有事情正常工作后,我意识到我可能可以使用 JJWT 做类似的事情。所以我最终做的是使用 Gson 执行对象的 JSON 编码,并将生成的 JSON 字符串作为声明附加。因此,当我想要收回自定义声明时,我会将声明提取为字符串,并使用 Gson 库将其转换回 POJO。

GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();

JwtConsumer jwtConsumer = getConsumer();

JwtClaims jwtClaims = jwtConsumer.processToClaims(token);
String userStr = jwtClaims.getClaimValue("user", String.class);
User user = gson.fromJson(userStr, User.class);
Run Code Online (Sandbox Code Playgroud)