PyJWT validate custom claims

Question:

Been using authlib for a while and it has been real easy to validate both the existence of a claim but also its value. According to the example:

claims_options = {
    "iss": { "essential": True, "value": "https://idp.example.com" },
    "aud": { "essential": True, "value": "api1" },
    "email": { "essential": True, "value": "[email protected]" },
 }

claims = jwt.decode(token, jwk, claims_options=claims_options)
claims.validate()

However, with PyJWT I find it to be a bit unclear. I only seem to be able to check for the existence of a claim but not its value (aud and iss obviously works):

decoded_token = jwt.decode(
    token,
    key,
    audience="api1",
    issuer="issuer"
    algorithms=["RS256"],
    options={"require": ["exp", "iss", "aud", "email"]}
)

This is even mentioned in the documentation. However, the documentation seem incomplete. Simply put, is it possible to validate custom claim values or do I simply need to manually parse the decoded token and look for my desired values?

Asked By: Frankster

||

Answers:

In PyJWT you can validate the issuer and audience, not just the existence of the claim but also the value. For custom claims the situation is different as mentioned on the end of my answer.

The values for the validation of audience and issuer are optional parameters after the options in the decode function.

The documentation mentions this under the options parameter

verify_aud=True but will be ignored if verify_signature is False.
Check that aud (audience) claim matches audience

So the conclusion is, that you need to parse custum claims manually.

import jwt
token = jwt.encode({"iss":"me", "aud":"you"}, "secret", "HS256")
print(token)
decoded_token = jwt.decode(token, "secret", ["HS256"], 
                           {"verify_aud":"true", "verify_iss":"true"}, 
                           audience="you", issuer="me")
print(decoded_token)

If you create the token like shown above, the output will be:

{‘iss’: ‘me’, ‘aud’: ‘you’}

If you change the "aud" claim in the token to a different value, you’ll get an exception:

jwt.exceptions.InvalidAudienceError: Invalid audience

Regarding custom claims, the part that was added to the question after I wrote about the audience and issuer claims, the documentation is IMHO quite clear:

require=[] list of claims that must be present. E.g. require=["exp", "iat", "nbf"]. Only verifies that the claims exists. Does NOT verify that the claims are valid.

And there’s also no place where you could add the values. Even for audience and issuer these values are provided as optional parameters instead of being part of the options dictionary.

So the conclusion is that you would need to verify custom claims manually after you successfully decoded the token.

Answered By: jps
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.