33# Licensed under the MIT License.
44# ------------------------------------
55from azure .core .credentials import AccessToken
6- from azure .identity import DefaultAzureCredential , KnownAuthorities , SharedTokenCacheCredential
6+ from azure .identity import (
7+ DefaultAzureCredential ,
8+ InteractiveBrowserCredential ,
9+ KnownAuthorities ,
10+ SharedTokenCacheCredential ,
11+ )
712from azure .identity ._constants import EnvironmentVariables
13+ from azure .identity ._credentials .managed_identity import ImdsCredential , MsiCredential
814from six .moves .urllib_parse import urlparse
915
1016from helpers import mock_response
@@ -32,11 +38,12 @@ def test_default_credential_authority():
3238
3339 def exercise_credentials (authority_kwarg , expected_authority = None ):
3440 expected_authority = expected_authority or authority_kwarg
41+
3542 def send (request , ** _ ):
36- scheme , netloc , path , _ , _ , _ = urlparse (request .url )
37- assert scheme == "https"
38- assert netloc == expected_authority
39- assert path .startswith ("/" + tenant_id )
43+ url = urlparse (request .url )
44+ assert url . scheme == "https"
45+ assert url . netloc == expected_authority
46+ assert url . path .startswith ("/" + tenant_id )
4047 return response
4148
4249 # environment credential configured with client secret should respect authority
@@ -46,7 +53,7 @@ def send(request, **_):
4653 EnvironmentVariables .AZURE_TENANT_ID : tenant_id ,
4754 }
4855 with patch ("os.environ" , environment ):
49- transport = Mock (send = send )
56+ transport = Mock (send = send )
5057 access_token , _ = DefaultAzureCredential (authority = authority_kwarg , transport = transport ).get_token ("scope" )
5158 assert access_token == expected_access_token
5259
@@ -59,3 +66,38 @@ def send(request, **_):
5966 # all credentials not representing managed identities should use a specified authority or default to public cloud
6067 exercise_credentials ("authority.com" )
6168 exercise_credentials (None , KnownAuthorities .AZURE_PUBLIC_CLOUD )
69+
70+
71+ def test_exclude_options ():
72+ def assert_credentials_not_present (chain , * excluded_credential_classes ):
73+ actual = {c .__class__ for c in chain .credentials }
74+ assert len (actual )
75+
76+ # no unexpected credential is in the chain
77+ excluded = set (excluded_credential_classes )
78+ assert len (actual & excluded ) == 0
79+
80+ # only excluded credentials have been excluded from the default
81+ default = {c .__class__ for c in DefaultAzureCredential ().credentials }
82+ assert actual <= default # n.b. we know actual is non-empty
83+ assert default - actual <= excluded
84+
85+ # with no environment variables set, ManagedIdentityCredential = ImdsCredential
86+ with patch ("os.environ" , {}):
87+ credential = DefaultAzureCredential (exclude_managed_identity_credential = True )
88+ assert_credentials_not_present (credential , ImdsCredential , MsiCredential )
89+
90+ # with $MSI_ENDPOINT set, ManagedIdentityCredential = MsiCredential
91+ with patch ("os.environ" , {"MSI_ENDPOINT" : "spam" }):
92+ credential = DefaultAzureCredential (exclude_managed_identity_credential = True )
93+ assert_credentials_not_present (credential , ImdsCredential , MsiCredential )
94+
95+ if SharedTokenCacheCredential .supported ():
96+ credential = DefaultAzureCredential (exclude_shared_token_cache_credential = True )
97+ assert_credentials_not_present (credential , SharedTokenCacheCredential )
98+
99+ # interactive auth is excluded by default
100+ credential = DefaultAzureCredential (exclude_interactive_browser_credential = False )
101+ actual = {c .__class__ for c in credential .credentials }
102+ default = {c .__class__ for c in DefaultAzureCredential ().credentials }
103+ assert actual - default == {InteractiveBrowserCredential }
0 commit comments