2016-11-21 98 views
2

我使用Auth0 java-jwt庫來生成JWT令牌,但是一旦生成,我無法驗證令牌。Auth0 java-jwt庫無法驗證有效令牌

這是我用它來生成令牌代碼:

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

令牌:eyJ0eXBlIjoi SldUIiwiYWxnIjoiSFMyNTYifQ.eyJ1c2VyIjp7ImlkIjoyLCJlbWFpbCI6InNhbnRob3NoQHh5ei5jb20iLCJwYXNzd29yZCI6IiQyYSQxMCRHSlNNRGtRRUEvRVNsRENJcVlud0R1Ly45YWRqRWRQalVvSWVKUmlsSmpSeHh6N2s2Q01xQyIsImZpcnN0X25hbWUiOiJzYW50aG9zaCIsImxhc3RfbmFtZSI6Imt1bWFyIiwic3RhdHVzIjoxLCJ0aXRsZSI6IkFzc29jIiwicm9sZXMiOlt7ImlkIjoxLCJyb2xlIjoiVVNFUiJ9XX0sImVtYWlsIjoic2FudGhvc2hAeHl6LmNvbSJ9.0SHNCgUWOijpYv7xcNoPiCwg_OFZQnsdi5l7YhCsSjU

當我使用相同的JWT令牌使用它失敗Auth0方法來驗證它(總是以一個簽名異常結束):

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類):

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解碼解碼。

我的假設是否正確。這是圖書館中的錯誤還是我錯了?

回答

1

使用的JWTVerifier版本假設你通過祕密Base64url編碼,因此它使用它爲重點,以驗證簽名之前自動解碼。

鑑於sfnd984f94j3fjn是實際的祕密和你的JWTVerifier版本自動Base64url解碼無論你通過它,需要在Base64url編碼sfnd984f94j3fjn並通過編碼版本JWTVerifier

事情與此類似:

import org.apache.commons.codec.binary.Base64; 

// ... 

Base64 encoder = new Base64(true); 

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

你可以看到下面的一行JWTVerifier類的版本的祕密發生的自動解碼你使用:

hmac.init(new SecretKeySpec(decoder.decodeBase64(secret), algorithm)); 

有關此更新的最新版本的庫似乎並不假定Base64url編碼。

+1

他們應該更新他們的文檔。它不明顯。謝謝。 – swordfish

+0

根據[此提交](https://github.com/auth0/java-jwt/commit/1e6f68764b26f62d39b04da6eca878c0989c6e5a),祕密不再被認爲是Base64,因此您使用的版本和在線文檔。 –