JWT中的类强制转换异常 [英] Class cast exception in JWT

查看:632
本文介绍了JWT中的类强制转换异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JwtBuilder创建令牌字符串.但是,当使用键提取值时,它给出的是ClassCastException.为了提供更好的理解,下面提供了代码段:

I am creating a token string using JwtBuilder. But while extracting a value using a key, it is giving ClassCastException. For better understanding code snippet are provided below:

创建令牌:

private JwtBuilder getJwtBuilder(
        String jti,
        Long issuedAt,
        Long expiredAt,
        Long businessAccountId,
        Long consumerAccountId,
        String deviceId
) {
    JwtBuilder builder = Jwts.builder();
    builder.setIssuer("SO");
    builder.setSubject(TokenConstant.TOKEN_SUBJECT);
    builder.setId(jti);
    builder.setIssuedAt(new Date(issuedAt));
    builder.setExpiration(new Date(expiredAt));
    builder.claim(TokenConstant.BUSINESS_ACCOUNT_ID, businessAccountId);
    builder.claim(TokenConstant.DEVICE_ID, deviceId);
    builder.signWith(SignatureAlgorithm.HS512, secretKey);
    return builder;
}

解码令牌:

private JsonWebToken decodeToken(String jsonWebToken) {
    try {
        Jws<Claims> map = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(jsonWebToken);
        Claims claims = map.getBody();
        return getJsonWebTokenFromClaims(claims);
    } catch (SignatureException | MalformedJwtException e) {
        throw new InvalidTokenException(e.getMessage());
    }
}

private JsonWebToken getJsonWebTokenFromClaims(Claims claims) {
    JsonWebToken token = new JsonWebToken();
    token.jti = claims.getId();
    token.expirationTime = claims.getExpiration().getTime();
    token.issuedAt = claims.getIssuedAt().getTime();
    token.deviceId = (String) claims.get(TokenConstant.DEVICE_ID);
    token.businessAccountId =  (Long) claims.get(TokenConstant.BUSINESS_ACCOUNT_ID);
    return token;
}

例外:

2018-04-23 10:27:04.476错误b.c.i.s.c.MyExceptionHandler- 应用程序错误:{} java.lang.ClassCastException:java.lang.Integer 不能转换为java.lang.Long

2018-04-23 10:27:04.476 ERROR b.c.i.s.c.MyExceptionHandler - Application error: {} java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long

jwt版本:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.6.0</version>
</dependency>

如您所见,将Integer类型的值强制转换为Long类型时,我的代码遇到错误.我无法理解,为什么Object类型被隐式转换为Integer?

As you can see that my code is getting an error while casting Integer type value to a Long type. I am unable to understand, why Object type is converted to Integer implicitly?

推荐答案

我建议将jwt依赖项的版本升级到版本0.9.0.

I would suggest upgrading the version of your jwt dependency to version 0.9.0.

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

此问题在此处报告为 Github中的一个问题,表示自动绑定基于设置为索赔的较小值的数据类型.我正在复制问题的确切陈述,以进行详细说明.

The issue was reported here as an issue in Github which indicates the auto binding to the data type based on smaller values set as a claim. I am copying the exact statement from the issue to elaborate more.

  String claimName = "long"
  Long claimVal = new Long(5)
  String compact = Jwts.builder().setClaims([(claimName): claimVal]).compact();
  Claims claims = Jwts.parser().parse(compact).body as Claims
  // `claims.get` throws `RequiredTypeException`
  assert claims.get(claimName, Long) == claimVal

在这里,杰克逊发现5足够小以适合整数和 因此取消编组,而不是预期的长.

Here, Jackson finds that a 5 is small enough to fit in the Integer and so unmarshalls into it, instead of expected Long.

更糟糕的是,当值足够大时(≥ 2 ^ 31),Jackson会切换到Long,因此总是天真地进行编码 get()-s整数将停止工作:

What makes matters worse is that when a value is large enough (≥ 2^31), Jackson will switch to Long and so code that naively always get()-s Integer will stop working:

但是,该问题已在此拉取请求中得到解决,并且在jwt库的较新发行版本.

However, the issue has been fixed in this pull request and is available in the newer released version of the jwt library.

更新库后,可以使用以下代码在没有RequiredTypeException的情况下获得适当的值.

After updating the library you can get the proper value without having a RequiredTypeException using the following code.

// businessAccountId is declared as Long I guess
token.businessAccountId = claims.get(TokenConstant.BUSINESS_ACCOUNT_ID, Long.class);

希望能解决您的问题.

Hope that fixes your problem.

这篇关于JWT中的类强制转换异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆