@@ -15,6 +15,8 @@ def _str2bytes(raw):
1515 except : # Otherwise we treat it as bytes and return it as-is
1616 return raw
1717
18+ def _encode_thumbprint (thumbprint ):
19+ return base64 .urlsafe_b64encode (binascii .a2b_hex (thumbprint )).decode ()
1820
1921class AssertionCreator (object ):
2022 def create_normal_assertion (
@@ -65,7 +67,11 @@ def __call__(self):
6567
6668
6769class JwtAssertionCreator (AssertionCreator ):
68- def __init__ (self , key , algorithm , sha1_thumbprint = None , headers = None ):
70+ def __init__ (
71+ self , key , algorithm , sha1_thumbprint = None , headers = None ,
72+ * ,
73+ sha256_thumbprint = None ,
74+ ):
6975 """Construct a Jwt assertion creator.
7076
7177 Args:
@@ -80,13 +86,15 @@ def __init__(self, key, algorithm, sha1_thumbprint=None, headers=None):
8086 RSA and ECDSA algorithms require "pip install cryptography".
8187 sha1_thumbprint (str): The x5t aka X.509 certificate SHA-1 thumbprint.
8288 headers (dict): Additional headers, e.g. "kid" or "x5c" etc.
89+ sha256_thumbprint (str): The x5t#S256 aka X.509 certificate SHA-256 thumbprint.
8390 """
8491 self .key = key
8592 self .algorithm = algorithm
8693 self .headers = headers or {}
94+ if sha256_thumbprint : # https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.8
95+ self .headers ["x5t#S256" ] = _encode_thumbprint (sha256_thumbprint )
8796 if sha1_thumbprint : # https://tools.ietf.org/html/rfc7515#section-4.1.7
88- self .headers ["x5t" ] = base64 .urlsafe_b64encode (
89- binascii .a2b_hex (sha1_thumbprint )).decode ()
97+ self .headers ["x5t" ] = _encode_thumbprint (sha1_thumbprint )
9098
9199 def create_normal_assertion (
92100 self , audience , issuer , subject = None , expires_at = None , expires_in = 600 ,
0 commit comments