From af9a305cc6595b134df3ff2e94ca203132108f10 Mon Sep 17 00:00:00 2001 From: Justin Richer Date: Mon, 15 Feb 2021 16:31:40 -0500 Subject: [PATCH 1/4] Add unencoded payload option, per RFC7797 --- jose/jws.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/jose/jws.py b/jose/jws.py index 63ebb9b9..cf52b42f 100644 --- a/jose/jws.py +++ b/jose/jws.py @@ -17,7 +17,7 @@ from jose.utils import base64url_decode -def sign(payload, key, headers=None, algorithm=ALGORITHMS.HS256): +def sign(payload, key, headers=None, algorithm=ALGORITHMS.HS256, unencoded=False): """Signs a claims set and returns a JWS string. Args: @@ -29,6 +29,8 @@ def sign(payload, key, headers=None, algorithm=ALGORITHMS.HS256): headers will override the default headers. algorithm (str, optional): The algorithm to use for signing the the claims. Defaults to HS256. + unencoded (boolean, optional): If True, the payload is not wrapped + in base64url encoding. Returns: str: The string representation of the header, claims, and signature. @@ -47,7 +49,7 @@ def sign(payload, key, headers=None, algorithm=ALGORITHMS.HS256): raise JWSError('Algorithm %s not supported.' % algorithm) encoded_header = _encode_header(algorithm, additional_headers=headers) - encoded_payload = _encode_payload(payload) + encoded_payload = _encode_payload(payload, unencoded) signed_output = _sign_header_and_claims(encoded_header, encoded_payload, algorithm, key) return signed_output @@ -151,7 +153,7 @@ def _encode_header(algorithm, additional_headers=None): return base64url_encode(json_header) -def _encode_payload(payload): +def _encode_payload(payload, unencoded): if isinstance(payload, Mapping): try: payload = json.dumps( @@ -160,8 +162,10 @@ def _encode_payload(payload): ).encode('utf-8') except ValueError: pass - - return base64url_encode(payload) + if unencoded: + return payload + else: + return base64url_encode(payload) def _sign_header_and_claims(encoded_header, encoded_claims, algorithm, key): From 4db8f073726bb7115c493c08d29be49e645fa2c1 Mon Sep 17 00:00:00 2001 From: Justin Richer Date: Mon, 15 Feb 2021 16:32:22 -0500 Subject: [PATCH 2/4] move typ: JWT default header to JWT instead of JWS, closes #204 --- jose/jws.py | 1 - jose/jwt.py | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/jose/jws.py b/jose/jws.py index cf52b42f..6f35b75a 100644 --- a/jose/jws.py +++ b/jose/jws.py @@ -137,7 +137,6 @@ def get_unverified_claims(token): def _encode_header(algorithm, additional_headers=None): header = { - "typ": "JWT", "alg": algorithm } diff --git a/jose/jwt.py b/jose/jwt.py index ee3b98d4..c1f702b2 100644 --- a/jose/jwt.py +++ b/jose/jwt.py @@ -61,6 +61,14 @@ def encode(claims, key, algorithm=ALGORITHMS.HS256, headers=None, access_token=N claims['at_hash'] = calculate_at_hash(access_token, ALGORITHMS.HASHES[algorithm]) + # if a type isn't passed in, set it here + if not headers: + headers = { + 'typ': 'JWT' + } + elif 'typ' not in headers: + headers['typ'] = 'JWT' + return jws.sign(claims, key, headers=headers, algorithm=algorithm) From e9000a5ac7b25f17842e114187266e0fb245cf94 Mon Sep 17 00:00:00 2001 From: Justin Richer Date: Tue, 16 Feb 2021 11:03:01 -0500 Subject: [PATCH 3/4] remove whitespace --- jose/jwt.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jose/jwt.py b/jose/jwt.py index c1f702b2..c88877ad 100644 --- a/jose/jwt.py +++ b/jose/jwt.py @@ -68,7 +68,6 @@ def encode(claims, key, algorithm=ALGORITHMS.HS256, headers=None, access_token=N } elif 'typ' not in headers: headers['typ'] = 'JWT' - return jws.sign(claims, key, headers=headers, algorithm=algorithm) From 593ff2f8425cb99dad91f9ce92e77a4b0a485e8a Mon Sep 17 00:00:00 2001 From: Justin Richer Date: Wed, 17 Feb 2021 10:58:36 -0500 Subject: [PATCH 4/4] updated JWS test for updated expected headers --- tests/test_jws.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_jws.py b/tests/test_jws.py index dd273398..e6d7d60d 100644 --- a/tests/test_jws.py +++ b/tests/test_jws.py @@ -133,8 +133,7 @@ def test_add_headers(self, payload): expected_headers = { 'test': 'header', - 'alg': 'HS256', - 'typ': 'JWT', + 'alg': 'HS256' } token = jws.sign(payload, 'secret', headers=additional_headers)