@@ -75,9 +75,10 @@ def _parse_pfx(pfx_path, passphrase_bytes):
75
75
x5c = [
76
76
'\n ' .join (cert_pem .splitlines ()[1 :- 1 ]) # Strip the "--- header ---" and "--- footer ---"
77
77
]
78
+ sha256_thumbprint = cert .fingerprint (hashes .SHA256 ()).hex () # cryptography 0.7+
78
79
sha1_thumbprint = cert .fingerprint (hashes .SHA1 ()).hex () # cryptography 0.7+
79
80
# 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
81
82
82
83
83
84
def _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
741
742
client_assertion = client_credential ['client_assertion' ]
742
743
else :
743
744
headers = {}
745
+ sha1_thumbprint = sha256_thumbprint = None
744
746
passphrase_bytes = _str2bytes (
745
747
client_credential ["passphrase" ]
746
748
) if client_credential .get ("passphrase" ) else None
747
749
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 (
749
751
client_credential ["private_key_pfx_path" ],
750
752
passphrase_bytes )
751
753
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
763
765
raise ValueError (
764
766
"client_credential needs to follow this format "
765
767
"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
767
769
and isinstance (client_credential .get ('public_certificate' ), str )
768
770
): # Then we treat the public_certificate value as PEM content
769
771
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
+ }
770
782
assertion = JwtAssertionCreator (
771
- private_key , algorithm = "RS256" ,
772
- sha1_thumbprint = sha1_thumbprint , headers = headers )
783
+ private_key , headers = headers , ** assertion_params )
773
784
client_assertion = assertion .create_regenerative_assertion (
774
785
audience = authority .token_endpoint , issuer = self .client_id ,
775
786
additional_claims = self .client_claims or {})
0 commit comments