2016-11-21 6 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 декодирует все, что вы передаете его, вам нужно кодировать sfnd984f94j3fjn в Base64url и передавать кодированную версию 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, поэтому может существовать несоответствие между используемой версией и онлайн-документы. –

 Смежные вопросы

  • Нет связанных вопросов^_^