This article describes how it is possible to validate a Keyloak access token and performing signature verification.

The RSA realm public key is uploaded in order to verify the access token signature

The example is illustrated using jwt.io debugger debugger, but could be used by any tool leveraging this methodology to verify the Keycloak Access Token viability.

1. Get an access token

A Keycloak access token is obtained from the token endpoint

  • https://localhost:8080/auth/realms/master/protocol/openid-connect/token
ACCESS_TOKEN=$(curl \
> -d "client_id=admin-cli" \
> -d "username=admin" \
> -d "password=admin" \
> -d "grant_type=password" \
> "https://localhost:8080/auth/realms/master/protocol/openid-connect/token" | jq -r '.access_token')
  

echo $ACCESS_TOKEN
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJYQmNYSDJQbHdoeFhXeXlGdmRtdnhZeGVIOTZwQl80ZGZjU3VZQWFUQk9JIn0.eyJqdGkiOiI3MWFjNDkzOS0wM2NiLTRjZTItYjA3Mi0wOGZhN2UxYjdmMzciLCJleHAiOjE1NjAyMzk5MDMsIm5iZiI6MCwiaWF0IjoxNTYwMjM5ODQzLCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjgwODAvYXV0aC9yZWFsbXMvbWFzdGVyIiwic3ViIjoiZDNlYTEzMDYtZjBmOS00YjI1LWI3YzUtZTY0ZGZiZGY5NDllIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiYWRtaW4tY2xpIiwiYXV0aF90aW1lIjowLCJzZXNzaW9uX3N0YXRlIjoiMDE2MmU4YzMtMjViMy00ZmQ5LTg0MTYtZTI4YmQyN2I2MWJkIiwiYWNyIjoiMSIsInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiYWRtaW4ifQ.MOu-XeCdt6M7ZJiYjQyo_hAtV3xEtmRaL6cxE-YdpsEoirm-QrQztPWFx0R6I7j6gkUuxum59zYSRS9ZPq9T207db7oKTqTEL_9WsrJXG0aCbkmpSL3En3q2zyiCKfbA4YrPYciHJkTF8LFhTgPWaXII7IwiyumDvcyl7wq_qDMJsihfM_Ewu86CrQzNs7UBirb40JiA6DeBipkI46T57E93FhA3lmRw_6IcDVVKxAiy5eQWpFwVJ7-g_jr7LW4AmhI_dSwwnfYI3JViX2V2Jw0AsveCb7sPAApAU3JdA3t2GpdGsjJDrNYaxrtq3yL7wzTQbYWvRzjp1309qK1YKw

This access token contains 3 parts :

  • header
  • payload
  • signature (using realm RSA public key)

2) Retrieving Realm RSA public key

The realm RSA public key is retrieved from the endpoint

  • https://localhost:8080/auth/realms/master/protocol/openid-connect/certs
curl -v https://localhost:8080/auth/realms/master/protocol/openid-connect/certs | jq
{
  "keys": [
    {
      "kid": "XBcXH2PlwhxXWyyFvdmvxYxeH96pB_4dfcSuYAaTBOI",
      "kty": "RSA",
      "alg": "RS256",
      "use": "sig",
      "n": "tg9Gyx05dRi6CDYtiRBeagGiK4XBF9iqoBNFBKogolM2FUj-qLWL7us4hygvIije5gCColPa0Nv0VLm4mDzyDJDzkBPMOIHmz4_30JinP60jRyYzsR6tYlwqse_wm99mOP3gCNlPpYiV1KEZNCDA9WQ30CwXsBj3wyQeWRparr6Ne3LkGHVcPduAc2nwZ4io5rN8FwrO9JG88Fq69gAySR8xWB7GciJtMtJU0ic4eXzF7BCHL2RzaY9_BI2U1S-StlB-q2XW_DgEbD9n1dJEkiaEMPgjABIu_VSItnM6FQjKrG_du2zo6oL24QaC9_6A04EahPeGLrGZcGeEm3Jezw",
      "e": "AQAB",
      "x5c": [
        "MIICmzCCAYMCBgFrQiMxODANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMTkwNjEwMTYwMzUxWhcNMjkwNjEwMTYwNTMxWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2D0bLHTl1GLoINi2JEF5qAaIrhcEX2KqgE0UEqiCiUzYVSP6otYvu6ziHKC8iKN7mAIKiU9rQ2/RUubiYPPIMkPOQE8w4gebPj/fQmKc/rSNHJjOxHq1iXCqx7/Cb32Y4/eAI2U+liJXUoRk0IMD1ZDfQLBewGPfDJB5ZGlquvo17cuQYdVw924BzafBniKjms3wXCs70kbzwWrr2ADJJHzFYHsZyIm0y0lTSJzh5fMXsEIcvZHNpj38EjZTVL5K2UH6rZdb8OARsP2fV0kSSJoQw+CMAEi79VIi2czoVCMqsb927bOjqgvbhBoL3/oDTgRqE94YusZlwZ4Sbcl7PAgMBAAEwDQYJKoZIhvcNAQELBQADggEBACg+mpDcPj+epf2ko7vO4ZvAVNqhUw+BpXbmtA9VsNGpHDHBCNkmZRSdYMftfo078tAd8zkFm8+l0SE8DlqaBOT1Cf2kIKNXxHtKJXE3BqVlMxnz6GFtn10TdTGa3P4RxBXRbyCmCr4lU7kJzJL5rODV9MFTlkhBBrSHxcT+PKlUe3/hnN2TC5q8T9IhKkiO2FvcMVloGkqbx/U563YXzGHESCtcCM9hQVWixP0CmJLXjXrP4IXLmGgpw+c6ra3rYpaZYHJ/VcsMQgWYollKfWjRjwIxOd58UX2/oT0bWgysohUe3NUQ89XnnxN6/055qN7z5sGt0P2btw2S0Zhzs3o="
      ],
      "x5t": "bqcNPiHy1E1SWp7_AkHgaEPBjEc",
      "x5t#S256": "z9smYdiAGegGY3WGmyvqmUMgpGZDVZI6c43y6mNAmWw"
    }
  ]
}

3. Obtaining a certificate file for the realm public key (.pem format)

The x5c filed value is copied between —–BEGIN CERTIFICATE—–

—–END CERTIFICATE—– directives .

-----BEGIN CERTIFICATE-----
MIICmzCCAYMCBgFrQiMxODANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZtYXN0ZXIwHhcNMTkwNjEwMTYwMzUxWhcNMjkwNjEwMTYwNTMxWjARMQ8wDQYDVQQDDAZtYXN0ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2D0bLHTl1GLoINi2JEF5qAaIrhcEX2KqgE0UEqiCiUzYVSP6otYvu6ziHKC8iKN7mAIKiU9rQ2/RUubiYPPIMkPOQE8w4gebPj/fQmKc/rSNHJjOxHq1iXCqx7/Cb32Y4/eAI2U+liJXUoRk0IMD1ZDfQLBewGPfDJB5ZGlquvo17cuQYdVw924BzafBniKjms3wXCs70kbzwWrr2ADJJHzFYHsZyIm0y0lTSJzh5fMXsEIcvZHNpj38EjZTVL5K2UH6rZdb8OARsP2fV0kSSJoQw+CMAEi79VIi2czoVCMqsb927bOjqgvbhBoL3/oDTgRqE94YusZlwZ4Sbcl7PAgMBAAEwDQYJKoZIhvcNAQELBQADggEBACg+mpDcPj+epf2ko7vO4ZvAVNqhUw+BpXbmtA9VsNGpHDHBCNkmZRSdYMftfo078tAd8zkFm8+l0SE8DlqaBOT1Cf2kIKNXxHtKJXE3BqVlMxnz6GFtn10TdTGa3P4RxBXRbyCmCr4lU7kJzJL5rODV9MFTlkhBBrSHxcT+PKlUe3/hnN2TC5q8T9IhKkiO2FvcMVloGkqbx/U563YXzGHESCtcCM9hQVWixP0CmJLXjXrP4IXLmGgpw+c6ra3rYpaZYHJ/VcsMQgWYollKfWjRjwIxOd58UX2/oT0bWgysohUe3NUQ89XnnxN6/055qN7z5sGt0P2btw2S0Zhzs3o= 
-----END CERTIFICATE----- 

4. Displaying and verifying the access token (using jwt.io)

This is done in 3 steps :

  • (1) getting hold of the access token
    • This will allow to display all teh access token field
  • (2) verification of the access token fields
    • The validation of the access token consists also of verifying each of the fields
      (Such a task can be done either by keycloak, or locally by program)
  • (3) Signature verification
    • This step is done using the realm RSA public key obtained previously

5. Illustration using Jwt.io

The jwt.io allow to display the information of the access token, and verify the signature.

5.1 Displaying the access token


The access_token is copied into the jwt.io debugger.
The access token fields ae displayed, and invalid signature is reported , as the signature field has not yet been completed.

keycloak access token and performing signature verification
5.2 Validating the signature

The signature is validated by copying teh PEM certificate obtained previously in the verify signature section (public key section)

Once this is done, the signature toggles to « Signature verified » to idicate that the access token signature has been verified.

Keycloak Access Token verification example
janua
Les derniers articles par janua (tout voir)