Skip to content

Commit 9f1bf3a

Browse files
authored
Identity not use is chained (#31328)
* not use is_chained * update
1 parent 674698c commit 9f1bf3a

16 files changed

Lines changed: 81 additions & 84 deletions

File tree

sdk/identity/azure-identity/azure/identity/_credentials/azd_cli.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from azure.core.exceptions import ClientAuthenticationError
1717

1818
from .. import CredentialUnavailableError
19-
from .._internal import resolve_tenant
19+
from .._internal import resolve_tenant, within_dac
2020
from .._internal.decorators import log_get_token
2121

2222
CLI_NOT_FOUND = (
@@ -75,11 +75,9 @@ def __init__(
7575
tenant_id: str = "",
7676
additionally_allowed_tenants: Optional[List[str]] = None,
7777
process_timeout: int = 10,
78-
_is_chained: bool = False,
7978
) -> None:
8079

8180
self.tenant_id = tenant_id
82-
self._is_chained = _is_chained
8381
self._additionally_allowed_tenants = additionally_allowed_tenants or []
8482
self._process_timeout = process_timeout
8583

@@ -123,7 +121,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken:
123121
)
124122
if tenant:
125123
command += " --tenant-id " + tenant
126-
output = _run_command(command, self._process_timeout, _is_chained=self._is_chained)
124+
output = _run_command(command, self._process_timeout)
127125

128126
token = parse_token(output)
129127
if not token:
@@ -133,7 +131,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken:
133131
f"To mitigate this issue, please refer to the troubleshooting guidelines here at "
134132
f"https://aka.ms/azsdk/python/identity/azdevclicredential/troubleshoot."
135133
)
136-
if self._is_chained:
134+
if within_dac.get():
137135
raise CredentialUnavailableError(message=message)
138136
raise ClientAuthenticationError(message=message)
139137

@@ -189,7 +187,7 @@ def sanitize_output(output: str) -> str:
189187
return re.sub(r"\"token\": \"(.*?)(\"|$)", "****", output)
190188

191189

192-
def _run_command(command: str, timeout: int, _is_chained: bool = False) -> str:
190+
def _run_command(command: str, timeout: int) -> str:
193191
# Ensure executable exists in PATH first. This avoids a subprocess call that would fail anyway.
194192
if shutil.which(EXECUTABLE_NAME) is None:
195193
raise CredentialUnavailableError(message=CLI_NOT_FOUND)
@@ -223,7 +221,7 @@ def _run_command(command: str, timeout: int, _is_chained: bool = False) -> str:
223221
message = sanitize_output(ex.stderr)
224222
else:
225223
message = "Failed to invoke Azure Developer CLI"
226-
if _is_chained:
224+
if within_dac.get():
227225
raise CredentialUnavailableError(message=message) from ex
228226
raise ClientAuthenticationError(message=message) from ex
229227
except OSError as ex:

sdk/identity/azure-identity/azure/identity/_credentials/azure_cli.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from azure.core.exceptions import ClientAuthenticationError
1717

1818
from .. import CredentialUnavailableError
19-
from .._internal import _scopes_to_resource, resolve_tenant
19+
from .._internal import _scopes_to_resource, resolve_tenant, within_dac
2020
from .._internal.decorators import log_get_token
2121

2222

@@ -53,11 +53,9 @@ def __init__(
5353
tenant_id: str = "",
5454
additionally_allowed_tenants: Optional[List[str]] = None,
5555
process_timeout: int = 10,
56-
_is_chained: bool = False,
5756
) -> None:
5857

5958
self.tenant_id = tenant_id
60-
self._is_chained = _is_chained
6159
self._additionally_allowed_tenants = additionally_allowed_tenants or []
6260
self._process_timeout = process_timeout
6361

@@ -97,7 +95,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken:
9795
)
9896
if tenant:
9997
command += " --tenant " + tenant
100-
output = _run_command(command, self._process_timeout, _is_chained=self._is_chained)
98+
output = _run_command(command, self._process_timeout)
10199

102100
token = parse_token(output)
103101
if not token:
@@ -107,7 +105,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken:
107105
f"To mitigate this issue, please refer to the troubleshooting guidelines here at "
108106
f"https://aka.ms/azsdk/python/identity/azclicredential/troubleshoot."
109107
)
110-
if self._is_chained:
108+
if within_dac.get():
111109
raise CredentialUnavailableError(message=message)
112110
raise ClientAuthenticationError(message=message)
113111

@@ -165,7 +163,7 @@ def sanitize_output(output: str) -> str:
165163
return re.sub(r"\"accessToken\": \"(.*?)(\"|$)", "****", output)
166164

167165

168-
def _run_command(command: str, timeout: int, _is_chained: bool = False) -> str:
166+
def _run_command(command: str, timeout: int) -> str:
169167
# Ensure executable exists in PATH first. This avoids a subprocess call that would fail anyway.
170168
if shutil.which(EXECUTABLE_NAME) is None:
171169
raise CredentialUnavailableError(message=CLI_NOT_FOUND)
@@ -198,7 +196,7 @@ def _run_command(command: str, timeout: int, _is_chained: bool = False) -> str:
198196
message = sanitize_output(ex.stderr)
199197
else:
200198
message = "Failed to invoke Azure CLI"
201-
if _is_chained:
199+
if within_dac.get():
202200
raise CredentialUnavailableError(message=message) from ex
203201
raise ClientAuthenticationError(message=message) from ex
204202
except OSError as ex:

sdk/identity/azure-identity/azure/identity/_credentials/azure_powershell.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from .azure_cli import get_safe_working_dir
1515
from .. import CredentialUnavailableError
16-
from .._internal import _scopes_to_resource, resolve_tenant
16+
from .._internal import _scopes_to_resource, resolve_tenant, within_dac
1717
from .._internal.decorators import log_get_token
1818

1919

@@ -67,11 +67,9 @@ def __init__(
6767
tenant_id: str = "",
6868
additionally_allowed_tenants: Optional[List[str]] = None,
6969
process_timeout: int = 10,
70-
_is_chained: bool = False
7170
) -> None:
7271

7372
self.tenant_id = tenant_id
74-
self._is_chained = _is_chained
7573
self._additionally_allowed_tenants = additionally_allowed_tenants or []
7674
self._process_timeout = process_timeout
7775

@@ -109,7 +107,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken:
109107
)
110108
command_line = get_command_line(scopes, tenant_id)
111109
output = run_command_line(command_line, self._process_timeout)
112-
token = parse_token(output, _is_chained=self._is_chained)
110+
token = parse_token(output)
113111
return token
114112

115113

@@ -155,13 +153,13 @@ def start_process(args: List[str]) -> "subprocess.Popen":
155153
return proc
156154

157155

158-
def parse_token(output: str, _is_chained: bool = False) -> AccessToken:
156+
def parse_token(output: str) -> AccessToken:
159157
for line in output.split():
160158
if line.startswith("azsdk%"):
161159
_, token, expires_on = line.split("%")
162160
return AccessToken(token, int(expires_on))
163161

164-
if _is_chained:
162+
if within_dac.get():
165163
raise CredentialUnavailableError(message='Unexpected output from Get-AzAccessToken: "{}"'.format(output))
166164
raise ClientAuthenticationError(message='Unexpected output from Get-AzAccessToken: "{}"'.format(output))
167165

sdk/identity/azure-identity/azure/identity/_credentials/browser.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
from .. import CredentialUnavailableError
1616
from .._constants import DEVELOPER_SIGN_ON_CLIENT_ID
17-
from .._internal import AuthCodeRedirectServer, InteractiveCredential, wrap_exceptions
17+
from .._internal import AuthCodeRedirectServer, InteractiveCredential, wrap_exceptions, within_dac
1818

1919

2020
class InteractiveBrowserCredential(InteractiveCredential):
@@ -78,7 +78,6 @@ def __init__(self, **kwargs: Any) -> None:
7878
else:
7979
self._parsed_url = None
8080

81-
self._is_chained = kwargs.pop("_is_chained", False)
8281
self._login_hint = kwargs.pop("login_hint", None)
8382
self._timeout = kwargs.pop("timeout", 300)
8483
self._server_class = kwargs.pop("_server_class", AuthCodeRedirectServer)
@@ -148,11 +147,11 @@ def _request_token(self, *scopes: str, **kwargs: Any) -> Dict:
148147
except socket.error as ex:
149148
raise CredentialUnavailableError(message="Couldn't start an HTTP server.") from ex
150149
if "access_token" not in result and "error_description" in result:
151-
if self._is_chained:
150+
if within_dac.get():
152151
raise CredentialUnavailableError(message=result["error_description"])
153152
raise ClientAuthenticationError(message=result.get("error_description"))
154153
if "access_token" not in result:
155-
if self._is_chained:
154+
if within_dac.get():
156155
raise CredentialUnavailableError(message="Failed to authenticate user")
157156
raise ClientAuthenticationError(message="Failed to authenticate user")
158157

sdk/identity/azure-identity/azure/identity/_credentials/default.py

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from azure.core.credentials import AccessToken
1010
from .._constants import EnvironmentVariables
11-
from .._internal import get_default_authority, normalize_authority
11+
from .._internal import get_default_authority, normalize_authority, within_dac
1212
from .azure_powershell import AzurePowerShellCredential
1313
from .browser import InteractiveBrowserCredential
1414
from .chained import ChainedTokenCredential
@@ -170,37 +170,28 @@ def __init__(self, **kwargs: Any) -> None: # pylint: disable=too-many-statement
170170
try:
171171
# username and/or tenant_id are only required when the cache contains tokens for multiple identities
172172
shared_cache = SharedTokenCacheCredential(
173-
username=shared_cache_username,
174-
tenant_id=shared_cache_tenant_id,
175-
authority=authority,
176-
_is_chained=True,
177-
**kwargs
173+
username=shared_cache_username, tenant_id=shared_cache_tenant_id, authority=authority, **kwargs
178174
)
179175
credentials.append(shared_cache)
180176
except Exception as ex: # pylint:disable=broad-except
181177
_LOGGER.info("Shared token cache is unavailable: '%s'", ex)
182178
if not exclude_visual_studio_code_credential:
183-
credentials.append(VisualStudioCodeCredential(_is_chained=True, **vscode_args))
179+
credentials.append(VisualStudioCodeCredential(**vscode_args))
184180
if not exclude_cli_credential:
185-
credentials.append(AzureCliCredential(process_timeout=process_timeout, _is_chained=True))
181+
credentials.append(AzureCliCredential(process_timeout=process_timeout))
186182
if not exclude_powershell_credential:
187-
credentials.append(AzurePowerShellCredential(process_timeout=process_timeout, _is_chained=True))
183+
credentials.append(AzurePowerShellCredential(process_timeout=process_timeout))
188184
if not exclude_developer_cli_credential:
189-
credentials.append(AzureDeveloperCliCredential(process_timeout=process_timeout, _is_chained=True))
185+
credentials.append(AzureDeveloperCliCredential(process_timeout=process_timeout))
190186
if not exclude_interactive_browser_credential:
191187
if interactive_browser_client_id:
192188
credentials.append(
193189
InteractiveBrowserCredential(
194-
tenant_id=interactive_browser_tenant_id,
195-
client_id=interactive_browser_client_id,
196-
_is_chained=True,
197-
**kwargs
190+
tenant_id=interactive_browser_tenant_id, client_id=interactive_browser_client_id, **kwargs
198191
)
199192
)
200193
else:
201-
credentials.append(
202-
InteractiveBrowserCredential(tenant_id=interactive_browser_tenant_id, _is_chained=True, **kwargs)
203-
)
194+
credentials.append(InteractiveBrowserCredential(tenant_id=interactive_browser_tenant_id, **kwargs))
204195

205196
super(DefaultAzureCredential, self).__init__(*credentials)
206197

@@ -226,5 +217,7 @@ def get_token(self, *scopes: str, **kwargs) -> AccessToken:
226217
"%s acquired a token from %s", self.__class__.__name__, self._successful_credential.__class__.__name__
227218
)
228219
return token
229-
230-
return super(DefaultAzureCredential, self).get_token(*scopes, **kwargs)
220+
within_dac.set(True)
221+
token = super(DefaultAzureCredential, self).get_token(*scopes, **kwargs)
222+
within_dac.set(False)
223+
return token

sdk/identity/azure-identity/azure/identity/_credentials/silent.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from azure.core.exceptions import ClientAuthenticationError
1414

1515
from .. import CredentialUnavailableError
16-
from .._internal import resolve_tenant, validate_tenant_id
16+
from .._internal import resolve_tenant, validate_tenant_id, within_dac
1717
from .._internal.decorators import wrap_exceptions
1818
from .._internal.msal_client import MsalClient
1919
from .._internal.shared_token_cache import NO_TOKEN
@@ -38,7 +38,6 @@ def __init__(
3838
# authenticate in the tenant that produced the record unless "tenant_id" specifies another
3939
self._tenant_id = tenant_id or self._auth_record.tenant_id
4040
validate_tenant_id(self._tenant_id)
41-
self._is_chained = kwargs.pop("_is_chained", False)
4241
self._cache = kwargs.pop("_cache", None)
4342
self._cache_persistence_options = kwargs.pop("cache_persistence_options", None)
4443
self._client_applications: Dict[str, PublicClientApplication] = {}
@@ -61,7 +60,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken:
6160
self._initialize()
6261

6362
if not self._cache:
64-
if self._is_chained:
63+
if within_dac.get():
6564
raise CredentialUnavailableError(message="Shared token cache unavailable")
6665
raise ClientAuthenticationError(message="Shared token cache unavailable")
6766

sdk/identity/azure-identity/azure/identity/_credentials/vscode.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from azure.core.exceptions import ClientAuthenticationError
1212
from .._exceptions import CredentialUnavailableError
1313
from .._constants import AzureAuthorityHosts, AZURE_VSCODE_CLIENT_ID, EnvironmentVariables
14-
from .._internal import normalize_authority, validate_tenant_id
14+
from .._internal import normalize_authority, validate_tenant_id, within_dac
1515
from .._internal.aad_client import AadClient, AadClientBase
1616
from .._internal.get_token_mixin import GetTokenMixin
1717
from .._internal.decorators import log_get_token
@@ -29,7 +29,6 @@ def __init__(self, **kwargs: Any) -> None:
2929
super(_VSCodeCredentialBase, self).__init__()
3030

3131
user_settings = get_user_settings()
32-
self._is_chained = kwargs.pop("_is_chained", False)
3332
self._cloud = user_settings.get("azure.cloud", "AzureCloud")
3433
self._refresh_token = None
3534
self._unavailable_reason = ""
@@ -162,7 +161,7 @@ def get_token(self, *scopes: str, **kwargs: Any) -> AccessToken:
162161
" to troubleshoot this issue."
163162
)
164163
raise CredentialUnavailableError(message=error_message)
165-
if self._is_chained:
164+
if within_dac.get():
166165
try:
167166
token = super(VisualStudioCodeCredential, self).get_token(*scopes, **kwargs)
168167
return token

sdk/identity/azure-identity/azure/identity/_internal/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
resolve_tenant,
1515
validate_tenant_id,
1616
within_credential_chain,
17+
within_dac,
1718
)
1819

1920

@@ -47,6 +48,7 @@ def _scopes_to_resource(*scopes) -> str:
4748
"normalize_authority",
4849
"resolve_tenant",
4950
"within_credential_chain",
51+
"within_dac",
5052
"wrap_exceptions",
5153
"validate_tenant_id",
5254
]

sdk/identity/azure-identity/azure/identity/_internal/shared_token_cache.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ def __init__(
9292
self._authority = normalize_authority(authority) if authority else get_default_authority()
9393
environment = urlparse(self._authority).netloc
9494
self._environment_aliases = KNOWN_ALIASES.get(environment) or frozenset((environment,))
95-
self._is_chained = kwargs.pop("_is_chained", False)
9695
self._username = username
9796
self._tenant_id = tenant_id
9897
self._cache = kwargs.pop("_cache", None)

sdk/identity/azure-identity/azure/identity/_internal/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from .._constants import EnvironmentVariables, KnownAuthorities
1414

1515
within_credential_chain = ContextVar("within_credential_chain", default=False)
16+
within_dac = ContextVar("within_dac", default=False)
1617

1718
_LOGGER = logging.getLogger(__name__)
1819

0 commit comments

Comments
 (0)