1

I have JWT generated by keyCloack, RS256 something like this

sample:

eyJhbGciOwia2lkIiA6ICJtSG1lajZEc09GaV9MejdSMjhzWjdMWkxBRXVzIn0.eyBzA2MzQvOTcwNjM1L1NNUyIsIi83Ni83NS9TTVMiXSwicHJYW1lIjoidGVzdDEwNUB1c2VyLmNvbSIsInVzZXJOYW1lIjoidGVzdDEwNUB1c2VyLmNvbSIsInVzZXJJZCI6IjU4NDM2NmQ4LWU5NDItNGJhNy04OGVlLWMyZTBlODhmZmY5ZCIsImVtYWlsIjoidGVzdDEwNUB1c2VyLmNvbSJ9.4TgC1MLyUl1P36oD6FafBCh0peEaCBmkyLheVjnlBu8uePl9xgEN6wdeWe

I need to decode and validate this token using keycloack certificate.

i can reach the keycloack certificate over api.

https://xxx.xxx.com.tr/auth/realms/myrealm/protocol/openid-connect/certs

in the response, I have x5c field.

{
    "keys": [
        {
            "kid": "j6DsCpPOz1RXJhtPR28sZ7LZLAEus",
            "kty": "RSA",
            "alg": "RS256",
            "use": "sig",
            "n": "m0oTFvyLhLGIciXfndxc7uhIKE2-q9nJQKByd0FVYe8Cd4CHDpTzzcYdPWRR-1_VKQ75wqpybRt-LnnTKPNCXrPtPDRn2GFihtYyyO8VjeVtnz-iYJJAHkdp25HlMtX9l-VjnQX9s70-lbMmCVCRTerw",
            "e": "AQAB",
            "x5c": [
                "MIICnTCCAYUCBgFzh2ZkQzANBgkqhkiG9w0BAQ50F/bO9PpWzJglQkU3q8CAwEAATANBgkqhkiG9w01faO/9ZzyiLMLsorUKzYPNAxc7Q9rLE0J2MCWfapx3/E4yyNjISuB1HpS5iF44OEhGHJlw7JQeogcZat0enB8yyXtP/cgBhCnrWwfugX8rHsWfHakBGdsoazR9w=="
            ],
            "x5t": "YF6LE97opzsTtD-yLNx9-Lo",
            "x5t#S256": "SdNCfMbCjvcq-JY3iiGAj7De9Hal_0Cck-bDFK3Ow"
        }
    ]
}

I can validate this jwt over https://jwt.io/ if I put the x5c part within ----CERTIFICATE----- tag

-----BEGIN CERTIFICATE-----
MIICnTCCAYUCBgFzh2ZkQzANBgkqhkiG9w0BAQ50F/bO9PpWzJglQkU3q8CAwEAATANBgkqhkiG9w01faO/9ZzyiLMLsorUKzYPNAxc7Q9rLE0J2MCWfapx3/E4yyNjISuB1HpS5iF44OEhGHJlw7JQeogcZat0enB8yyXtP/cgBhCnrWwfugX8rHsWfHakBGdsoazR9w==
-----END CERTIFICATE----- 

how can I verify same thing in Java?

I tried couple of things but it failed.

sakirow
  • 189
  • 1
  • 5
  • 18
  • Does this answer your question? [Verifying JWT Signature using public key endpoint](https://stackoverflow.com/questions/44639891/verifying-jwt-signature-using-public-key-endpoint) – jps Aug 06 '20 at 10:30
  • @jps not it doesn't I added solution below – sakirow Aug 07 '20 at 13:23
  • if you are writing plugin to keycloak, using AppAuthManager helps you to verify the token. It isn't what you are looking but might help someone. – Muhammed Yalçın Kuru Aug 10 '20 at 08:07

2 Answers2

3

I found the way.

First, we need to login keycloack console, you can reach the public key related with realm.

now you have publickey from keycloak and JWT from user.

you need to import related libraries first.

<dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.11.2</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-impl</artifactId>
            <version>0.11.2</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-jackson</artifactId>
            <version>0.11.2</version>
            <scope>runtime</scope>
        </dependency>

after that here is the logic.

String token = "ghfghfdhdhdfhdfghdhdfhdfhdfhhdf";
String rsaPublicKey = "awdasdsadaefafafaef5df65d4f";
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(rsaPublicKey));
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey = kf.generatePublic(keySpec);

we have publickey, we need to verify it

Jws<Claims> jwt = null;
try {
    jwt = Jwts.parserBuilder()
                        .setSigningKey(publicKey)
                        .build()
                        .parseClaimsJws(token);
            } catch (Exception e) {
                // if you get error, that means token is invalid.
            }
sakirow
  • 189
  • 1
  • 5
  • 18
1

I think you can use jose4j library for that.

HttpsJwks httpsJkws = new HttpsJwks("https://xxx.xxx.com.tr/auth/realms/myrealm/protocol/openid-connect/certs");
HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws);


// Use JwtConsumerBuilder to construct an appropriate JwtConsumer, which will
// be used to validate and process the JWT. But, in this case, provide it with
// the HttpsJwksVerificationKeyResolver instance rather than setting the
// verification key explicitly.

jwtConsumer = new JwtConsumerBuilder()
    // ... other set up of the JwtConsumerBuilder ...
    .setVerificationKeyResolver(httpsJwksKeyResolver)
    // ...
    .build();
matejko219
  • 1,601
  • 10
  • 14
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/26871280) – Carsten Løvbo Andersen Aug 06 '20 at 12:25
  • @Carsten Løvbo Andersen You are absolutely right. I edited my answer. – matejko219 Aug 06 '20 at 12:38