首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Auth0 java-jwt库无法验证有效的令牌。

Auth0 java-jwt库无法验证有效的令牌。
EN

Stack Overflow用户
提问于 2016-11-21 23:54:10
回答 1查看 3.1K关注 0票数 3

我正在使用Auth0 java-jwt库来生成JWT令牌,但是一旦生成,我就无法验证这些令牌。

这是我用来生成令牌的代码:

代码语言:javascript
运行
复制
final JWTSigner signer = new JWTSigner(secret);
final HashMap<String, Object> claims = new HashMap<String, Object>();
claims.put("user", user);
claims.put("email", user.getEmail());
final String jwt = signer.sign(claims);
return jwt;

这是我的秘密和令牌(它在https://jwt.io/中正确验证):

: sfnd984f94j3fjn eyJ0eXBlIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.eyJ1c2VyIjp7ImlkIjoyLCJlbWFpbCI6InNhbnRob3NoQHh5ei5jb20iLCJwYXNzd29yZCI6IiQyYSQxMCRHSlNNRGtRRUEvRVNsRENJcVlud0R1Ly45YWRqRWRQalVvSWVKUmlsSmpSeHh6N2s2Q01xQyIsImZpcnN0X25hbWUiOiJzYW50aG9zaCIsImxhc3RfbmFtZSI6Imt1bWFyIiwic3RhdHVzIjoxLCJ0aXRsZSI6IkFzc29jIiwicm9sZXMiOlt7ImlkIjoxLCJyb2xlIjoiVVNFUiJ9XX0sImVtYWlsIjoic2FudGhvc2hAeHl6LmNvbSJ9.0SHNCgUWOijpYv7xcNoPiCwg_OFZQnsdi5l7YhCsSjU 令牌

当我使用相同的JWT令牌使用Auth0方法验证它时,它会失败(总是以一个签名异常结束):

代码语言:javascript
运行
复制
try {           
    final JWTVerifier verifier = new JWTVerifier(secret);
    final Map<String, Object> claims= verifier.verify(jwt);
    final String email = (String)claims.get("email");
    user =  userService.loadUserByEmail(email);
} catch (UsernameNotFoundException e) {
    // Invalid Token
} catch (SignatureException e) {
    System.out.println(e.toString());
} catch (IOException e) { 
} catch (Exception e) { 
}

我调试了这个库,我认为这就是问题所在(在JWTVerifier类中):

代码语言:javascript
运行
复制
void verifySignature(String[] pieces, String algorithm) 
    throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {

    Mac hmac = Mac.getInstance(algorithm);
    hmac.init(new SecretKeySpec(decoder.decodeBase64(secret), algorithm));
    byte[] sig = hmac.doFinal(
        new StringBuilder(pieces[0]).append(".").append(pieces[1]).toString().getBytes());

    if (!Arrays.equals(sig, decoder.decodeBase64(pieces[2]))) {
        throw new SignatureException("signature verification failed");
    }
}

这在我看来是不对的,因为pieces[1]pieces[0]是用hmac.doFinal解码的,因为pieces[2]只是简单的base64解码。

我的假设是对的。这是图书馆里的错误还是我出了什么问题?

EN

Stack Overflow用户

回答已采纳

发布于 2016-11-22 09:32:24

正在使用的JWTVerifier 版本假定您传递的秘密是Base64url编码的,因此在使用作为验证签名的密钥之前,它会自动对其进行解码。

假设sfnd984f94j3fjn是实际的秘密,并且您的JWTVerifier版本会自动解码您传递给它的任何内容,则需要在Base64url中对 Base64url 进行编码,并将编码版本传递给 JWTVerifier.。

与此类似的是:

代码语言:javascript
运行
复制
import org.apache.commons.codec.binary.Base64;

// ...

Base64 encoder = new Base64(true);

encoder.encodeBase64("sfnd984f94j3fjn".getBytes());

您可以看到正在使用的JWTVerifier类版本的下一行发生的秘密自动解码:

代码语言:javascript
运行
复制
hmac.init(new SecretKeySpec(decoder.decodeBase64(secret), algorithm));

关于这方面的更新,最新版本的库似乎不采用Base64url编码。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40731578

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档