2016-02-27 78 views
0

我有令牌會從服務器來回客戶端上的每個請求使用Nimbus JOSE + JWT如何雨雲JOSE +智威湯遜驗證令牌簽名

碼資源用於創建JWT令牌:

public class TokenProvider { 

    String token = ""; 

    public String getToken(String email) { 
     try { 
      KeyPairGenerator keyGenerator = KeyPairGenerator.getInstance("RSA"); 
      keyGenerator.initialize(1024); 

      KeyPair kp = keyGenerator.genKeyPair(); 
      RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic(); 
      RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate(); 

      System.out.println("publicKey: " + publicKey); 
      System.out.println("privateKey: " + privateKey.toString()); 

      JWSSigner signer = new RSASSASigner(privateKey); 

      JWTClaimsSet claimsSet = new JWTClaimsSet(); 
      claimsSet.setSubject("RTH"); 
      claimsSet.setCustomClaim("email", email); 
      claimsSet.setCustomClaim("role", "USER"); 
      claimsSet.setIssuer("https://rth.com"); 
      claimsSet.setExpirationTime(new Date(new Date().getTime() + 60 * 1000)); 

      SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.RS256), claimsSet); 

      signedJWT.sign(signer); 
      token = signedJWT.serialize(); 
      TokenSaverAndValidatorDAO tokenSaver = new TokenSaverAndValidatorDAO(); 
      tokenSaver.saveTokenToDB(email, token); 

      signedJWT = SignedJWT.parse(token); 

      JWSVerifier verifier = new RSASSAVerifier(publicKey); 
      System.out.println("verifier: " + verifier); 
      System.out.println("verify method: " + signedJWT.verify(verifier)); 
      assertTrue(signedJWT.verify(verifier)); 
      assertEquals("RTH", signedJWT.getJWTClaimsSet().getSubject()); 
      assertEquals("https://rth.com", signedJWT.getJWTClaimsSet().getIssuer()); 
      assertTrue(new Date().before(signedJWT.getJWTClaimsSet().getExpirationTime())); 
     } catch (JOSEException | ParseException | NoSuchAlgorithmException ex) { 
      Logger.getLogger(TokenProvider.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     return token; 
    } 
} 

到目前爲止它的工作正常,但問題是我如何驗證從客戶端收到的令牌簽名?

API,只有一種方法看起來像驗證,但它只接受公鑰(RSAPublicKey)作爲參數而不是令牌。

任何人在JWT上使用這個庫的幫助。謝謝

回答

2

sample code做到這一點,但你有所有的代碼在你的問題做到這一點。

對於共享密鑰:

JWSVerifier verifier = new MACVerifier(sharedKey.getBytes()); 

如果您使用RSA密鑰(如你的例子),只需要提供公共密鑰:

JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey); 

然後問驗證簽名,注意它會拋出一個異常如果它是無效的:

boolean verifiedSignature = false; 

    try { 
     JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey); 
     verifiedSignature = signedJWT.verify(verifier); 
    } 
    catch (JOSEException e) { 
     System.err.println("Couldn't verify signature: " + e.getMessage()); 
    } 

一個完整的方法來做檢查令牌簽名可能如下所示:

public static boolean isSignatureValid(String token) { 
    // Parse the JWS and verify its RSA signature 
    SignedJWT signedJWT; 
    try { 
     signedJWT = SignedJWT.parse(token); 
     JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey); 
     return signedJWT.verify(verifier); 
    } catch (ParseException | JOSEException e) { 
     return false; 
    } 
}