-
Notifications
You must be signed in to change notification settings - Fork 239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong type of exception raised if required claim is missing in jwt.decode #197
Comments
You raise an interesting question: if a required claim is not provided, should that claim be considered "invalid"? I can definitely see your point that yes, it should be considered "invalid", but after reviewing the code I'm not so sure that I agree with you: def _validate_claims(claims, audience=None, issuer=None, subject=None,
algorithm=None, access_token=None, options=None):
...
# Check that all required claims are provided
for require_claim in [
e[len("require_"):] for e in options.keys() if e.startswith("require_") and options[e]
]:
if require_claim not in claims:
raise JWTError('missing required key "%s" among claims' % require_claim)
else:
options['verify_' + require_claim] = True # override verify when required
...
# Each of these blocks validates a claim value if the claim should be verified
# The `_validate_<claim>` functions all raise JWTClaimsError
if options.get('verify_iat'):
_validate_iat(claims)
if options.get('verify_nbf'):
_validate_nbf(claims, leeway=leeway)
... I think the original intent in the code was to classify errors for misconfiguration, decoding, or missing (required) claims as JWT errors, and to classify errors about the values of claims themselves as invalid value errors. To wit, the slightly more generic
In comparison, the
So the code differentiates between these two JWT claims (assume that the "issuer" claim is required): {
"aud": "..."
// required issuer claim is just completely missing from the claims
} // raises a JWTError versus: {
"aud": "..."
"iss": null // required issuer claim is provided, but decodes to None, which isn't a valid value
} // raises a JWTClaimsError Circling back around to the question you raised, I think that a completely missing claim should be handled differently than a claim value that is not valid. Now, that's not to say that your question is invalid to begin with. At the very least, the documentation and docstrings should make this difference very clear: Raises:
JWTError: If the signature is invalid in any way, including
decoding issues, missing claims, a non-JSON
header or claims section, or invalid signatures.
...
JWTClaimsError: If any provided claim value is invalid in any way. Would that rewording make the difference more clear? An additional idea would be to create a class JWTMissingClaimError(JWTError):
"Raised when a required JWT claim is not provided."
pass and raise that in I would be open to pull requests implementing either or both of those if you have the time. And I'll keep this issue open until it's fixed. |
Whoa, that's something I call a thorough answer 🙇 My original problem was that I couldn't tell apart "invalid signature" and "missing required claim" cases (just using the exception type). That would be solved by the proposed Another thing that I've now noticed is that we might interpret the term signature differently. To me signature means only the cryptographic signature, the one that
makes me think that here the term signature (its first occurrence) includes more, perhaps the JWT as a whole. If this is the case, perhaps I interpreted the original documentation ("JWTError: If the signature is invalid in any way") also differently than how it was meant. So, in order to avoid confusion, we should either agree on what signature means, or acknowledge, that we have differing interpretations. Off course this isn't just you or me making interpretations of the term, since this is public documentation. If there's a chance of misinterpretation, then the documentation could off course be improved. |
The documentation of
jwt.decode
says:When an explicitly required claim (one where
options["require_XXX"]
is set toTrue
) is missing, aJWTError
is raised. I think the implementation and the documentation contradict. I like what the documentation says, and wish that the implementation would deliver. So in this case I hope it would raise aJWTClaimsError
.The text was updated successfully, but these errors were encountered: