From 22669734c632b3848b66729db47c2c8003824b34 Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Tue, 19 Dec 2017 13:52:39 +0100 Subject: [PATCH 1/3] Do not fail in JWT decode() if at_hash claim is missing Fixes #75 --- jose/jwt.py | 5 ++--- tests/test_jwt.py | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/jose/jwt.py b/jose/jwt.py index 2da511fd..1cf41c7c 100644 --- a/jose/jwt.py +++ b/jose/jwt.py @@ -420,12 +420,11 @@ def _validate_at_hash(claims, access_token, algorithm): """ if 'at_hash' not in claims and not access_token: return + elif access_token and 'at_hash' not in claims: + return elif 'at_hash' in claims and not access_token: msg = 'No access_token provided to compare against at_hash claim.' raise JWTClaimsError(msg) - elif access_token and 'at_hash' not in claims: - msg = 'at_hash claim missing from token.' - raise JWTClaimsError(msg) try: expected_hash = calculate_at_hash(access_token, diff --git a/tests/test_jwt.py b/tests/test_jwt.py index 485fff52..beb6789f 100644 --- a/tests/test_jwt.py +++ b/tests/test_jwt.py @@ -468,8 +468,8 @@ def test_at_hash_missing_access_token(self, claims, key): def test_at_hash_missing_claim(self, claims, key): token = jwt.encode(claims, key) - with pytest.raises(JWTError): - jwt.decode(token, key, access_token='') + payload = jwt.decode(token, key, access_token='') + assert 'at_hash' not in payload def test_at_hash_unable_to_calculate(self, claims, key): token = jwt.encode(claims, key, access_token='') From a2cfd30d82507bc6048d6877bda349c96946a7bc Mon Sep 17 00:00:00 2001 From: Mathieu Leplatre Date: Tue, 19 Dec 2017 23:43:50 +0100 Subject: [PATCH 2/3] Address @mpdavis comments --- jose/jwt.py | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/jose/jwt.py b/jose/jwt.py index 1cf41c7c..3ba32507 100644 --- a/jose/jwt.py +++ b/jose/jwt.py @@ -408,21 +408,26 @@ def _validate_jti(claims): def _validate_at_hash(claims, access_token, algorithm): """ - Validates that the 'at_hash' parameter included in the claims matches - with the access_token returned alongside the id token as part of - the authorization_code flow. + Validates that the 'at_hash' is valid. + + Its value is the base64url encoding of the left-most half of the hash + of the octets of the ASCII representation of the access_token value, + where the hash algorithm used is the hash algorithm used in the alg + Header Parameter of the ID Token's JOSE Header. For instance, if the + alg is RS256, hash the access_token value with SHA-256, then take the + left-most 128 bits and base64url encode them. The at_hash value is a + case sensitive string. Use of this claim is OPTIONAL. Args: - claims (dict): The claims dictionary to validate. - access_token (str): The access token returned by the OpenID Provider. - algorithm (str): The algorithm used to sign the JWT, as specified by - the token headers. + claims (dict): The claims dictionary to validate. + access_token (str): The access token returned by the OpenID Provider. + algorithm (str): The algorithm used to sign the JWT, as specified by + the token headers. """ - if 'at_hash' not in claims and not access_token: - return - elif access_token and 'at_hash' not in claims: + if 'at_hash' not in claims: return - elif 'at_hash' in claims and not access_token: + + if not access_token: msg = 'No access_token provided to compare against at_hash claim.' raise JWTClaimsError(msg) @@ -432,7 +437,7 @@ def _validate_at_hash(claims, access_token, algorithm): except (TypeError, ValueError): msg = 'Unable to calculate at_hash to verify against token claims.' raise JWTClaimsError(msg) - + if claims['at_hash'] != expected_hash: raise JWTClaimsError('at_hash claim does not match access_token.') From a4cfabe32b55dcb4ee9d629c856ace355b6f7c9e Mon Sep 17 00:00:00 2001 From: Todd Date: Wed, 14 Nov 2018 23:09:11 -0500 Subject: [PATCH 3/3] Include docs and tests in sdists These are useful to downstreams, such as linux packagers. --- MANIFEST.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MANIFEST.in b/MANIFEST.in index a5021c60..8fb0e6e7 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,7 @@ include README.rst include LICENSE +include requirements.txt +include requirements-*.txt +include tox.ini +graft docs +graft tests