@@ -435,6 +435,251 @@ def test_pem_with_both_thumbprints_unknown_aad_uses_sha256(
435435 expected_thumbprint_value = self .test_sha256_thumbprint
436436 )
437437
438+ # Additional tests for SHA256-only with different authority types
439+ def test_pem_with_thumbprint_sha256_only_b2c_uses_sha256 (
440+ self , mock_jwt_creator_class , mock_authority_class ):
441+ """Test that B2C with only SHA256 thumbprint uses SHA-256"""
442+ authority = "https://contoso.b2clogin.com/contoso.onmicrosoft.com/B2C_1_susi"
443+ mock_authority = self ._setup_mocks (mock_authority_class , authority )
444+ mock_authority ._is_b2c = True
445+ mock_authority ._is_oidc = False
446+
447+ app = ConfidentialClientApplication (
448+ client_id = "my_client_id" ,
449+ client_credential = {
450+ "private_key" : self .test_private_key ,
451+ "thumbprint_sha256" : self .test_sha256_thumbprint ,
452+ },
453+ authority = authority
454+ )
455+
456+ self ._verify_assertion_params (
457+ mock_jwt_creator_class ,
458+ expected_algorithm = 'PS256' ,
459+ expected_thumbprint_type = 'sha256' ,
460+ expected_thumbprint_value = self .test_sha256_thumbprint
461+ )
462+
463+ def test_pem_with_thumbprint_sha256_only_ciam_uses_sha256 (
464+ self , mock_jwt_creator_class , mock_authority_class ):
465+ """Test that CIAM with only SHA256 thumbprint uses SHA-256"""
466+ authority = "https://contoso.ciamlogin.com/contoso.onmicrosoft.com"
467+ mock_authority = self ._setup_mocks (mock_authority_class , authority )
468+ mock_authority ._is_b2c = True
469+ mock_authority ._is_oidc = False
470+
471+ app = ConfidentialClientApplication (
472+ client_id = "my_client_id" ,
473+ client_credential = {
474+ "private_key" : self .test_private_key ,
475+ "thumbprint_sha256" : self .test_sha256_thumbprint ,
476+ },
477+ authority = authority
478+ )
479+
480+ self ._verify_assertion_params (
481+ mock_jwt_creator_class ,
482+ expected_algorithm = 'PS256' ,
483+ expected_thumbprint_type = 'sha256' ,
484+ expected_thumbprint_value = self .test_sha256_thumbprint
485+ )
486+
487+ def test_pem_with_thumbprint_sha256_only_adfs_uses_sha256 (
488+ self , mock_jwt_creator_class , mock_authority_class ):
489+ """Test that ADFS with only SHA256 thumbprint uses SHA-256 (even though ADFS prefers SHA1)"""
490+ authority = "https://adfs.contoso.com/adfs"
491+ self ._setup_mocks (mock_authority_class , authority )
492+
493+ app = ConfidentialClientApplication (
494+ client_id = "my_client_id" ,
495+ client_credential = {
496+ "private_key" : self .test_private_key ,
497+ "thumbprint_sha256" : self .test_sha256_thumbprint ,
498+ },
499+ authority = authority
500+ )
501+
502+ # When only SHA256 is provided, it should be used even for ADFS
503+ self ._verify_assertion_params (
504+ mock_jwt_creator_class ,
505+ expected_algorithm = 'PS256' ,
506+ expected_thumbprint_type = 'sha256' ,
507+ expected_thumbprint_value = self .test_sha256_thumbprint
508+ )
509+
510+ def test_pem_with_thumbprint_sha256_only_oidc_uses_sha256 (
511+ self , mock_jwt_creator_class , mock_authority_class ):
512+ """Test that OIDC generic with only SHA256 thumbprint uses SHA-256"""
513+ authority = "https://custom.oidc.authority.com/tenant"
514+ mock_authority = self ._setup_mocks (mock_authority_class , authority )
515+ mock_authority .is_adfs = False
516+ mock_authority ._is_b2c = True
517+ mock_authority ._is_oidc = True
518+
519+ app = ConfidentialClientApplication (
520+ client_id = "my_client_id" ,
521+ client_credential = {
522+ "private_key" : self .test_private_key ,
523+ "thumbprint_sha256" : self .test_sha256_thumbprint ,
524+ },
525+ authority = authority
526+ )
527+
528+ # When only SHA256 is provided, it should be used even for OIDC
529+ self ._verify_assertion_params (
530+ mock_jwt_creator_class ,
531+ expected_algorithm = 'PS256' ,
532+ expected_thumbprint_type = 'sha256' ,
533+ expected_thumbprint_value = self .test_sha256_thumbprint
534+ )
535+
536+ def test_pem_with_thumbprint_sha256_only_dsts_uses_sha256 (
537+ self , mock_jwt_creator_class , mock_authority_class ):
538+ """Test that dSTS with only SHA256 thumbprint uses SHA-256"""
539+ authority = "https://test-instance1-dsts.dsts.core.azure-test.net/dstsv2/common"
540+ mock_authority = self ._setup_mocks (mock_authority_class , authority )
541+ mock_authority .is_adfs = False
542+ mock_authority ._is_b2c = True
543+ mock_authority ._is_oidc = True
544+
545+ app = ConfidentialClientApplication (
546+ client_id = "my_client_id" ,
547+ client_credential = {
548+ "private_key" : self .test_private_key ,
549+ "thumbprint_sha256" : self .test_sha256_thumbprint ,
550+ },
551+ authority = authority
552+ )
553+
554+ # When only SHA256 is provided, it should be used even for dSTS
555+ self ._verify_assertion_params (
556+ mock_jwt_creator_class ,
557+ expected_algorithm = 'PS256' ,
558+ expected_thumbprint_type = 'sha256' ,
559+ expected_thumbprint_value = self .test_sha256_thumbprint
560+ )
561+
562+ # Tests for SHA1-only with different authority types
563+ def test_pem_with_thumbprint_sha1_only_b2c_uses_sha1 (
564+ self , mock_jwt_creator_class , mock_authority_class ):
565+ """Test that B2C with only SHA1 thumbprint uses SHA-1"""
566+ authority = "https://contoso.b2clogin.com/contoso.onmicrosoft.com/B2C_1_susi"
567+ mock_authority = self ._setup_mocks (mock_authority_class , authority )
568+ mock_authority ._is_b2c = True
569+ mock_authority ._is_oidc = False
570+
571+ app = ConfidentialClientApplication (
572+ client_id = "my_client_id" ,
573+ client_credential = {
574+ "private_key" : self .test_private_key ,
575+ "thumbprint" : self .test_sha1_thumbprint ,
576+ },
577+ authority = authority
578+ )
579+
580+ self ._verify_assertion_params (
581+ mock_jwt_creator_class ,
582+ expected_algorithm = 'RS256' ,
583+ expected_thumbprint_type = 'sha1' ,
584+ expected_thumbprint_value = self .test_sha1_thumbprint
585+ )
586+
587+ def test_pem_with_thumbprint_sha1_only_ciam_uses_sha1 (
588+ self , mock_jwt_creator_class , mock_authority_class ):
589+ """Test that CIAM with only SHA1 thumbprint uses SHA-1"""
590+ authority = "https://contoso.ciamlogin.com/contoso.onmicrosoft.com"
591+ mock_authority = self ._setup_mocks (mock_authority_class , authority )
592+ mock_authority ._is_b2c = True
593+ mock_authority ._is_oidc = False
594+
595+ app = ConfidentialClientApplication (
596+ client_id = "my_client_id" ,
597+ client_credential = {
598+ "private_key" : self .test_private_key ,
599+ "thumbprint" : self .test_sha1_thumbprint ,
600+ },
601+ authority = authority
602+ )
603+
604+ self ._verify_assertion_params (
605+ mock_jwt_creator_class ,
606+ expected_algorithm = 'RS256' ,
607+ expected_thumbprint_type = 'sha1' ,
608+ expected_thumbprint_value = self .test_sha1_thumbprint
609+ )
610+
611+ def test_pem_with_thumbprint_sha1_only_adfs_uses_sha1 (
612+ self , mock_jwt_creator_class , mock_authority_class ):
613+ """Test that ADFS with only SHA1 thumbprint uses SHA-1"""
614+ authority = "https://adfs.contoso.com/adfs"
615+ self ._setup_mocks (mock_authority_class , authority )
616+
617+ app = ConfidentialClientApplication (
618+ client_id = "my_client_id" ,
619+ client_credential = {
620+ "private_key" : self .test_private_key ,
621+ "thumbprint" : self .test_sha1_thumbprint ,
622+ },
623+ authority = authority
624+ )
625+
626+ self ._verify_assertion_params (
627+ mock_jwt_creator_class ,
628+ expected_algorithm = 'RS256' ,
629+ expected_thumbprint_type = 'sha1' ,
630+ expected_thumbprint_value = self .test_sha1_thumbprint
631+ )
632+
633+ def test_pem_with_thumbprint_sha1_only_oidc_uses_sha1 (
634+ self , mock_jwt_creator_class , mock_authority_class ):
635+ """Test that OIDC generic with only SHA1 thumbprint uses SHA-1"""
636+ authority = "https://custom.oidc.authority.com/tenant"
637+ mock_authority = self ._setup_mocks (mock_authority_class , authority )
638+ mock_authority .is_adfs = False
639+ mock_authority ._is_b2c = True
640+ mock_authority ._is_oidc = True
641+
642+ app = ConfidentialClientApplication (
643+ client_id = "my_client_id" ,
644+ client_credential = {
645+ "private_key" : self .test_private_key ,
646+ "thumbprint" : self .test_sha1_thumbprint ,
647+ },
648+ authority = authority
649+ )
650+
651+ self ._verify_assertion_params (
652+ mock_jwt_creator_class ,
653+ expected_algorithm = 'RS256' ,
654+ expected_thumbprint_type = 'sha1' ,
655+ expected_thumbprint_value = self .test_sha1_thumbprint
656+ )
657+
658+ def test_pem_with_thumbprint_sha1_only_dsts_uses_sha1 (
659+ self , mock_jwt_creator_class , mock_authority_class ):
660+ """Test that dSTS with only SHA1 thumbprint uses SHA-1"""
661+ authority = "https://test-instance1-dsts.dsts.core.azure-test.net/dstsv2/common"
662+ mock_authority = self ._setup_mocks (mock_authority_class , authority )
663+ mock_authority .is_adfs = False
664+ mock_authority ._is_b2c = True
665+ mock_authority ._is_oidc = True
666+
667+ app = ConfidentialClientApplication (
668+ client_id = "my_client_id" ,
669+ client_credential = {
670+ "private_key" : self .test_private_key ,
671+ "thumbprint" : self .test_sha1_thumbprint ,
672+ },
673+ authority = authority
674+ )
675+
676+ self ._verify_assertion_params (
677+ mock_jwt_creator_class ,
678+ expected_algorithm = 'RS256' ,
679+ expected_thumbprint_type = 'sha1' ,
680+ expected_thumbprint_value = self .test_sha1_thumbprint
681+ )
682+
438683
439684if __name__ == "__main__" :
440685 unittest .main ()
0 commit comments