解码时jwt签名异常

Posted

技术标签:

【中文标题】解码时jwt签名异常【英文标题】:jwt Signature exception while decoding 【发布时间】:2018-04-19 23:03:46 【问题描述】:

我在向 Spring Rest 服务添加安全性时遇到签名异常。请帮忙。

io.jsonwebtoken.SignatureException:JWT 签名与本地计算的签名不匹配。 JWT 有效性不能被断言,也不应该被信任。 在 io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:354)

//制作令牌

String token = Jwts.builder()
.setSubject(((User) auth.getPrincipal()).getUsername())
.signWith(SignatureAlgorithm.HS512, SECRET.getBytes("UTF-8"))
.compact();
res.addHeader(HEADER_STRING, TOKEN_PREFIX + token);

// 解码令牌

String token = request.getHeader(HEADER_STRING);
if (token != null) 
// parse the token.

        String jwt = token.replace(TOKEN_PREFIX, "");
        try 
            Claims claims = Jwts.parser()
            .setSigningKey(SECRET.getBytes("UTF-8"))
            .parseClaimsJws(jwt)
            .getBody();
            if (claims.getSubject() != null) 
                return new UsernamePasswordAuthenticationToken(claims.getSubject(), null, getAuthorities());
            
        

当我打印两者时,我得到以下文本。一是有额外的空间。仅当我使用 Rest 客户端访问服务时才会发生这种情况。测试类工作正常。

makeToken=eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJza3AifQ.XUEsUFF3qm6fOeCG8xDLuRWjyd4kOh4g01olU_BsRyfqyI66MRhqmK-mxrAWSD17Ylmj-fZRRZUTRqxCQixxXQ

解码令牌= eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJza3AifQ.XUEsUFF3qm6fOeCG8xDLuRWjyd4kOh4g01olU_BsRyfqyI66MRhqmK-mxrAWSD17Ylmj-fZRR ZUTRqxCQixxXQ

【问题讨论】:

查看客户端代码以删除标头中的多余空间。服务器代码似乎没问题 我发现了这个问题,在从 Rest Client(Mozilla 中的插件)获取 Bearer 令牌时,下一行是一个额外的空间。 【参考方案1】:

如果有人在解码 JWT 令牌时遇到同样的问题,那就晚了。

库 GitHub 链接:

https://github.com/auth0/JWTDecode.android

实施:

implementation ('com.auth0.android:jwtdecode:1.2.0')
    exclude group: 'com.android.support', module: 'appcompat-v7'

代码:

// token: eyJ0eXAiOiJKV1QiLCJhbxxxxxxx9.eyJpZC*********************UEFUSUVOVCIsImV4cCI6MTU2NTY5MzU5MCwib3JpZ0lhdCI6MTU2NTA4ODc5MH0.ZhPpZSFZL6EY-Mwrw0F*********MYmbw

private void getExpDate(String token) 
    JWT jwt = new JWT(token);
    Log.e(TAG,"Claim - id:"+jwt.getClaim("id").asString()+" - username:"+jwt.getClaim("username").asString()+" - role:"+jwt.getClaim("role").asString()+" - exp:"+jwt.getClaim("exp").asString());

Logcat 结果:

 E/PatientLogin: Claim - id:cd5dbe61-xxxx-xxxx-xxxx-xxxxxx - username:xxxx@gmail.com - role:PATIENT - exp:1565693590

测试 JWT 令牌: 如果您想检查您的 JWT 令牌,请使用以下链接。

https://jwt.io/

这是另一种可能也适合您的方法。这将有助于避免使用第三方库。

参考:Orignal post

decoded(token);

public static String decoded(String JWTEncoded) 
    String[] split = JWTEncoded.split("\\.");
    Log.e(TAG, "Header: " + getJson(split[0]));
    Log.e(TAG, "Body: " + getJson(split[1]));
    return getJson(split[1]);


private static String getJson(String strEncoded)
    String str_dec = "";
    try 
        byte[] decodedBytes = Base64.decode(strEncoded, Base64.URL_SAFE);
        str_dec = new String(decodedBytes, "UTF-8");
     catch (UnsupportedEncodingException e) 
        e.printStackTrace();
    
    return str_dec;

【讨论】:

以上是关于解码时jwt签名异常的主要内容,如果未能解决你的问题,请参考以下文章

django rest框架使用jwt RS256解码签名错误

tymon/jwt-auth Laravel:无法验证令牌签名

谷歌 OAuth JWT 签名验证

如何使用 pyJWT 验证此 JWT 上的签名?

JWT 令牌签名验证 javascript

使用 PHP 的 JWT“签名验证失败”