@@ -75,9 +75,10 @@ def _parse_pfx(pfx_path, passphrase_bytes):
7575 x5c = [
7676 '\n ' .join (cert_pem .splitlines ()[1 :- 1 ]) # Strip the "--- header ---" and "--- footer ---"
7777 ]
78+ sha256_thumbprint = cert .fingerprint (hashes .SHA256 ()).hex () # cryptography 0.7+
7879 sha1_thumbprint = cert .fingerprint (hashes .SHA1 ()).hex () # cryptography 0.7+
7980 # https://cryptography.io/en/latest/x509/reference/#x-509-certificate-object
80- return private_key , sha1_thumbprint , x5c
81+ return private_key , sha256_thumbprint , sha1_thumbprint , x5c
8182
8283
8384def _load_private_key_from_pem_str (private_key_pem_str , passphrase_bytes ):
@@ -741,11 +742,12 @@ def _build_client(self, client_credential, authority, skip_regional_client=False
741742 client_assertion = client_credential ['client_assertion' ]
742743 else :
743744 headers = {}
745+ sha1_thumbprint = sha256_thumbprint = None
744746 passphrase_bytes = _str2bytes (
745747 client_credential ["passphrase" ]
746748 ) if client_credential .get ("passphrase" ) else None
747749 if client_credential .get ("private_key_pfx_path" ):
748- private_key , sha1_thumbprint , x5c = _parse_pfx (
750+ private_key , sha256_thumbprint , sha1_thumbprint , x5c = _parse_pfx (
749751 client_credential ["private_key_pfx_path" ],
750752 passphrase_bytes )
751753 if client_credential .get ("public_certificate" ) is True and x5c :
@@ -763,13 +765,22 @@ def _build_client(self, client_credential, authority, skip_regional_client=False
763765 raise ValueError (
764766 "client_credential needs to follow this format "
765767 "https://msal-python.readthedocs.io/en/latest/#msal.ClientApplication.params.client_credential" )
766- if ("x5c" not in headers # So we did not run the pfx code path
768+ if ("x5c" not in headers # So the . pfx file contains no certificate
767769 and isinstance (client_credential .get ('public_certificate' ), str )
768770 ): # Then we treat the public_certificate value as PEM content
769771 headers ["x5c" ] = extract_certs (client_credential ['public_certificate' ])
772+ if sha256_thumbprint and not authority .is_adfs :
773+ assertion_params = {
774+ "algorithm" : "PS256" , "sha256_thumbprint" : sha256_thumbprint ,
775+ }
776+ else : # Fall back
777+ if not sha1_thumbprint :
778+ raise ValueError ("You shall provide a thumbprint in SHA1." )
779+ assertion_params = {
780+ "algorithm" : "RS256" , "sha1_thumbprint" : sha1_thumbprint ,
781+ }
770782 assertion = JwtAssertionCreator (
771- private_key , algorithm = "RS256" ,
772- sha1_thumbprint = sha1_thumbprint , headers = headers )
783+ private_key , headers = headers , ** assertion_params )
773784 client_assertion = assertion .create_regenerative_assertion (
774785 audience = authority .token_endpoint , issuer = self .client_id ,
775786 additional_claims = self .client_claims or {})
0 commit comments