# JWT RS256 Token Validation

**URL:** <https://discuss.konghq.com/t/jwt-rs256-token-validation/3438>\
**Category:** Questions\
**Created:** [May 3, 2019, 3:24pm UTC](https://discuss.konghq.com/t/jwt-rs256-token-validation/3438 "2019-05-03T15:24:57Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![flowdopip](https://yyz2.discourse-cdn.com/flex036/user_avatar/discuss.konghq.com/flowdopip/32/1704_2.png) [@flowdopip](https://discuss.konghq.com/u/flowdopip)\
**Post date:** [May 3, 2019, 3:24pm UTC](https://discuss.konghq.com/t/jwt-rs256-token-validation/3438/1 "2019-05-03T15:24:57Z")

</div>

Hi,

I´m trying to do a plugin to validate the integrity of an JWT Token emitted my IDP (IdentityServer 4).

Steps:

1. Retrieve the JWKS from the discovery endpoint, and filter for potential signing keys (e.g., any keys missing a public key or with a `kid` property).
2. Extract the JWT from the request’s authorization header and [decode it](https://jwt.io/#debugger-io).
3. Grab the `kid` property from the header of the decoded JWT.
4. Search your filtered JWKS for the key with the matching `kid` property.
5. Build a certificate using the corresponding `x5c` property in your JWKS.
6. Use the certificate to verify the JWT’s signature.

Im using the method verify of [https://github.com/Kong/kong/blob/master/kong/plugins/jwt/jwt\_parser.lua](https://github.com/Kong/kong/blob/master/kong/plugins/jwt/jwt_parser.lua) but im getting this error "Consumer Public Key is Invalid "

Any idea or help?

Thanks

---

<div class="post-metadata">

**Author:** ![flowdopip](https://yyz2.discourse-cdn.com/flex036/user_avatar/discuss.konghq.com/flowdopip/32/1704_2.png) [@flowdopip](https://discuss.konghq.com/u/flowdopip)\
**Post date:** [May 6, 2019, 2:37pm UTC](https://discuss.konghq.com/t/jwt-rs256-token-validation/3438/2 "2019-05-06T14:37:11Z")

</div>

i´ve done some advances on the plugin and its working now, with a little workaround.

I need to found a way to convert x5c to pem format, with that we plugin works well

---

<div class="post-metadata">

**Author:** ![Ronald](https://yyz2.discourse-cdn.com/flex036/user_avatar/discuss.konghq.com/ronald/32/1115_2.png) [@Ronald](https://discuss.konghq.com/u/Ronald)\
**Post date:** [June 17, 2019, 9:35am UTC](https://discuss.konghq.com/t/jwt-rs256-token-validation/3438/3 "2019-06-17T09:35:17Z")

</div>

Hi, did you open source your plugin? And did you solve the conversion issue?  
We need the same so it would be great if we could use your plugin.

---

<div class="post-metadata">

**Author:** ![Arun](https://yyz2.discourse-cdn.com/flex036/user_avatar/discuss.konghq.com/arun/32/1889_2.png) [@Arun](https://discuss.konghq.com/u/Arun)\
**Post date:** [June 17, 2019, 10:02am UTC](https://discuss.konghq.com/t/jwt-rs256-token-validation/3438/4 "2019-06-17T10:02:31Z")

</div>

Hi,

I had a similar requirement, to keep Kong and Azure in sync with respect to x5c and so on.

Because Azure rotate (lazy rotate) keys every so often it had to be a script that keeps the keys in sync, so I wrote a python script.  
Now I don’t think this is what you are looking for, but it might be useful to others, so apologies if I am distracting your ticket, but since its related, I will paste the script here.

```
import json
import requests
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.x509 import load_pem_x509_certificate

PEMSTART = "-----BEGIN CERTIFICATE-----\n"
PEMEND = "\n-----END CERTIFICATE-----\n"

kongURL = 'https://api.kong.myapp.com'
username = 'admin'
password = 'password'
tenantID = '121212-12121-1212121-121212'
azureURL = 'https://login.microsoftonline.com/'+tenantID+'/discovery/keys'

class JWT:
  def __init__ (self, algorithm, key, rsa_public_key):
    self.algorithm = algorithm
    self.key = key
    self.rsa_public_key = rsa_public_key

f = open("azure-apps.txt", "r")
for app in f:
  print("Processing App: " + app)

  # Get the consumer definitions from Kong
  consumerResponse = requests.get(kongURL+'/'+app.strip(), auth=(username, password))
  consumer = consumerResponse.json()
  appId = consumer['custom_id']
  consumerId = consumer['id']
  print('App ID: ' + appId)
  print('Consumer ID: ' + consumerId)

  # Get the consumer JWT details from Kong
  jwtResponse = requests.get(kongURL+'/'+consumerId+'/jwt', auth=(username, password))
  jwt = jwtResponse.json()
  kongKeys = list()
  for i in jwt['data']:
    key = i['key']
    if key:
      kongKeys.append(key)
  #print(kongKeys)

  # Get the keys/cert details from Azure
  azureResponse = requests.get(azureURL + "?appid=" + appId)
  azure = azureResponse.json()
  azureKeys = list()
  for i in azure['keys']:
    key = i['kid']
    if key:
      azureKeys.append(key)
  #print(azureKeys)

  # These are keys present in Azure but not in Kong
  keysToBeAdded = set(azureKeys) - set(kongKeys)
  print('Keys to be added: ' + ','.join(keysToBeAdded))

  # These are keys present in Kong but not in Azure
  keysToBeDeleted = set(kongKeys) - set(azureKeys)
  print('Keys to be deleted: ' + ','.join(keysToBeDeleted))

  # Add missing keys to Kong
  for key in keysToBeAdded:
    for i in azure['keys']:
      azureKey = i['kid']
      if azureKey == key:
        # Get the x509 cert and convert that to a PEM
        rawcert = ''.join(i['x5c'])
        cert_str = PEMSTART + rawcert + PEMEND
        #print(cert_str)
        cert_obj = load_pem_x509_certificate(cert_str.encode('ascii'), default_backend())
        pem = cert_obj.public_key().public_bytes(serialization.Encoding.PEM, serialization.PublicFormat.SubjectPublicKeyInfo)
        #print(pem)

        # Prepare jwt request to be sent to Kong
        dataObj = JWT('RS256', key, pem)
        data = json.dumps(dataObj. __dict__ )
        #print(data)
        headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
        response = requests.post(kongURL + '/' + consumerId + '/jwt', data=data, auth=(username, password), headers=headers)
        #print(response)
        if response.status_code == 201:
          print('Key ' + key + ' has been added to Kong')
        else:
          print('There was a problem adding key '+ key +' to Kong')

  # Delete redundant keys from Kong
  for key in keysToBeDeleted:
    response = requests.delete(kongURL+'/'+consumerId+'/jwt/' + key, auth=(username, password))
    #print(response)
    if response.status_code == 204:
      print('Key ' + key + ' has been deleted from Kong')
    else:
      print('There was a problem deleting key '+ key +' from Kong')

```

It will require an azure-apps.txt that contains the names of Azure apps. I use the custom\_id to store the Azure App ID

---

<div class="post-metadata">

**Author:** ![flowdopip](https://yyz2.discourse-cdn.com/flex036/user_avatar/discuss.konghq.com/flowdopip/32/1704_2.png) [@flowdopip](https://discuss.konghq.com/u/flowdopip)\
**Post date:** [June 18, 2019, 1:21pm UTC](https://discuss.konghq.com/t/jwt-rs256-token-validation/3438/5 "2019-06-18T13:21:15Z")

</div>

hi all,

Yes i already have a way to convert to pen. I will open-source the plugin soon. The idea is to have automatic rotation policy of the certificates.

I follow the same approach of this guys: [https://github.com/gbbirkisson/kong-plugin-jwt-keycloak](https://github.com/gbbirkisson/kong-plugin-jwt-keycloak)

On convertion.lua you have the code to convert

Thanks
