JWT中的类强制转换异常

问题描述 投票:2回答:2

我正在使用JwtBuilder创建一个令牌字符串。但是在使用密钥提取值时,它会给出ClassCastException。为了更好地理解,下面提供了代码段:

令牌创建:

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

jwt版本:

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

正如您所看到的,在将Integer类型值强制转换为Long类型时,我的代码出错了。我无法理解,为什么Object类型被隐含地转换为Integer

java spring-boot jwt
2个回答
4
投票

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

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

此问题在此处报告为an issue in Github,表示基于设置为声明的较小值自动绑定到数据类型。我正在复制问题中的确切陈述以进一步阐述。

  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小到足以适应整数,因此解开它,而不是预期的龙。

更糟糕的是,当一个值足够大(≥2^ 31)时,杰克逊将切换到Long,所以编码天真地总是得到() - s整数将停止工作:

但是,这个问题已在this pull request中得到修复,并且可以在jwt库的较新发布版本中找到。

更新库后,您可以使用以下代码获得正确的值,而无需使用RequiredTypeException

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

希望能解决你的问题。


0
投票

令牌创建文件从底部第3行你正在做“.longvalue()”。我认为你应该尝试将字段“business AccountId”的类型更改为Long

© www.soinside.com 2019 - 2024. All rights reserved.