I have tokens going back and forth from server to client on each request for resource using Nimbus JOSE + JWT
Code for creating JWT token:
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;
}
}
So far its working fine but the problem is how do I verify the token signature received back from client?
From the API, there is only one method which looks like it is for verification but its accepting only public Key (RSAPublicKey
) as parameter rather than token.
Anyone worked on JWT using this library please help. Thank you
There is sample code to do this, but you have all the code in place to do this in your question.
For a shared key:
JWSVerifier verifier = new MACVerifier(sharedKey.getBytes());
If you're using an RSA keypair (as in your example), you need only supply the public key:
JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) publicKey);
Then ask it to verify the signature, noting that it will throw an exception if it's invalid:
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());
}
A complete method to do check token signature might look like this:
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With