簡體   English   中英

如何在Nimbus JOSE + JWT中驗證令牌簽名

[英]How to verify token signature in Nimbus JOSE + JWT

在使用Nimbus JOSE + JWT的每次資源請求中,我都有從服務器到客戶端的來回令牌

用於創建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工作的任何人都請幫忙。 謝謝

示例代碼可以執行此操作,但是您已在問題中使用了所有代碼來執行此操作。

對於共享密鑰:

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;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM