Skip to content

Commit ec4ad99

Browse files
committed
check presence among claims
1 parent 1c3c1a6 commit ec4ad99

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Changelog
88
Major
99
"""""
1010

11+
* Require claim options added.
12+
`#98 <https://github.com/mpdavis/python-jose/pull/98>`_
1113
* Isolate and flesh out cryptographic backends to enable independent operation.
1214
`#114 <https://github.com/mpdavis/python-jose/issues/114>`_
1315
`#129 <https://github.com/mpdavis/python-jose/pull/129>`_

jose/jwt.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ def decode(token, key, algorithms=None, options=None, audience=None,
9797
'verify_sub': True,
9898
'verify_jti': True,
9999
'verify_at_hash': True,
100+
'require_aud': False,
101+
'require_iat': False,
102+
'require_exp': False,
103+
'require_nbf': False,
104+
'require_iss': False,
105+
'require_sub': False,
106+
'require_jti': False,
107+
'require_at_hash': False,
100108
'leeway': 0,
101109
}
102110
@@ -126,6 +134,14 @@ def decode(token, key, algorithms=None, options=None, audience=None,
126134
'verify_sub': True,
127135
'verify_jti': True,
128136
'verify_at_hash': True,
137+
'require_aud': False,
138+
'require_iat': False,
139+
'require_exp': False,
140+
'require_nbf': False,
141+
'require_iss': False,
142+
'require_sub': False,
143+
'require_jti': False,
144+
'require_at_hash': False,
129145
'leeway': 0,
130146
}
131147

@@ -455,6 +471,14 @@ def _validate_claims(claims, audience=None, issuer=None, subject=None,
455471
if isinstance(leeway, timedelta):
456472
leeway = timedelta_total_seconds(leeway)
457473

474+
for require_claim in [
475+
e[len("require_"):] for e in options.keys() if e.startswith("require_") and options[e]
476+
]:
477+
if require_claim not in claims:
478+
raise JWTError('missing required key "%s" among claims' % require_claim)
479+
else:
480+
options['verify_' + require_claim] = True # override verify when required
481+
458482
if not isinstance(audience, (string_types, type(None))):
459483
raise JWTError('audience must be a string or None')
460484

tests/test_jwt.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,3 +579,26 @@ def test_unverified_claims_list(self):
579579
def test_unverified_claims_object(self, claims, key):
580580
token = jwt.encode(claims, key)
581581
assert jwt.get_unverified_claims(token) == claims
582+
583+
@pytest.mark.parametrize(
584+
"claim,value", [
585+
("aud", "aud"),
586+
("ait", "ait"),
587+
("exp", datetime.utcnow() + timedelta(seconds=5)),
588+
("nbf", datetime.utcnow() - timedelta(seconds=5)),
589+
("iss", "iss"),
590+
("sub", "sub"),
591+
("jti", "jti"),
592+
]
593+
)
594+
def test_require(self, claims, key, claim, value):
595+
options = {"require_" + claim: True, "verify_" + claim: False}
596+
597+
token = jwt.encode(claims, key)
598+
with pytest.raises(JWTError):
599+
jwt.decode(token, key, options=options, audience=str(value))
600+
601+
new_claims = dict(claims)
602+
new_claims[claim] = value
603+
token = jwt.encode(new_claims, key)
604+
jwt.decode(token, key, options=options, audience=str(value))

0 commit comments

Comments
 (0)