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?
CodePudding user response:
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 ifverify_signature
isFalse
. Check thataud
(audience) claim matchesaudience
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.