Reputation: 168
I am trying to validate JWT Access token which generated by KeyCloak Authorization server.
I have copied public_key from http://ip-address:port/auth/realms/
For validating Access token i am using https://mvnrepository.com/artifact/com.auth0/java-jwt
and referring https://www.baeldung.com/java-jwt-token-decode for verifying signature.
Code I am trying:
String publicKey =<public_key from http://<ip>:<port>/auth/realms/<app> >
String accessToken =<valid access token from keycloak>
String[] chunks = accessToken.split("\\.");
Base64.Decoder decoder = Base64.getDecoder();
String header = new String(decoder.decode(chunks[0])); // {"alg":"RS256","typ" : "JWT","kid" : "dsssdssdf"}
String payload = new String(decoder.decode(chunks[1])); //{"exp":1632237161,"iat":1632236861,"auth_time":1632236854,"jt..."}
String signature = chunks[2]; // <signature from access token>
SignatureAlgorithm sa = SignatureAlgorithm.RS256;
String tokenWithoutSignature = chunks[0] + "." + chunks[1];
SecretKeySpec secretKeySpec = new SecretKeySpec(publicKey.getBytes(), sa.getJcaName());
DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, secretKeySpec);
if (!validator.isValid(tokenWithoutSignature, signature)) {
System.out.println("=============== Invalid access token");
} else {
System.out.println("============= valid access token");
}
After running above code following error observed:
java.lang.IllegalArgumentException: RSA Signature validation requires either a RSAPublicKey or RSAPrivateKey instance.
at io.jsonwebtoken.lang.Assert.isTrue(Assert.java:38)
at io.jsonwebtoken.impl.crypto.RsaSignatureValidator.<init>(RsaSignatureValidator.java:36)
at io.jsonwebtoken.impl.crypto.DefaultSignatureValidatorFactory.createSignatureValidator(DefaultSignatureValidatorFactory.java:43)
at io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator.<init>(DefaultJwtSignatureValidator.java:37)
at io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator.<init>(DefaultJwtSignatureValidator.java:32)
Can anyone please help here?
Upvotes: 1
Views: 4255
Reputation: 168
I try something like :
String publicKey =<public_key from http://<ip>:<port>/auth/realms/<app> >
byte[] decoded = Base64.getDecoder().decode(publicKey);
String algorithm = "RSA";
KeyFactory kf = KeyFactory.getInstance(algorithm);
PublicKey generatedPublic = kf.generatePublic(new X509EncodedKeySpec(decoded));
String accessToken =<valid access token from keycloak>
String[] chunks = accessToken.split("\\.");
Base64.Decoder decoder = Base64.getDecoder();
String header = new String(decoder.decode(chunks[0])); // {"alg":"RS256","typ" : "JWT","kid" : "dsssdssdf"}
String payload = new String(decoder.decode(chunks[1])); //{"exp":1632237161,"iat":1632236861,"auth_time":1632236854,"jt..."}
String signature = chunks[2]; // <signature from access token>
SignatureAlgorithm sa = SignatureAlgorithm.RS256;
String tokenWithoutSignature = chunks[0] + "." + chunks[1];
DefaultJwtSignatureValidator validator = new DefaultJwtSignatureValidator(sa, generatedPublic);
if (!validator.isValid(tokenWithoutSignature, signature)) {
System.out.println("=============== Invalid access token");
} else {
System.out.println("============= valid access token");
}
and It worked !!
Upvotes: 1