|
4 | 4 | # license information. |
5 | 5 | # -------------------------------------------------------------------------- |
6 | 6 | """Azure KeyVault pre-authentication.""" |
| 7 | + |
7 | 8 | from __future__ import annotations |
8 | 9 |
|
9 | 10 | import logging |
|
16 | 17 |
|
17 | 18 | from azure.common.credentials import get_cli_profile |
18 | 19 | from azure.core.credentials import TokenCredential |
| 20 | +from azure.core.exceptions import ClientAuthenticationError |
19 | 21 | from azure.identity import ( |
20 | 22 | AzureCliCredential, |
21 | 23 | AzurePowerShellCredential, |
@@ -150,27 +152,62 @@ def _build_cli_client( |
150 | 152 | ) -> AzureCliCredential: |
151 | 153 | """Build a credential from Azure CLI.""" |
152 | 154 | del kwargs |
153 | | - if tenant_id: |
154 | | - return AzureCliCredential(tenant_id=tenant_id) |
155 | | - return AzureCliCredential() |
| 155 | + if tenant_id is not None: |
| 156 | + try: |
| 157 | + logger.info("Creating Azure CLI credential with tenant_id") |
| 158 | + cred = AzureCliCredential(tenant_id=tenant_id) |
| 159 | + # Attempt to get a token immediately to validate the credential |
| 160 | + cred.get_token("https://management.azure.com/.default") |
| 161 | + return cred |
| 162 | + except ClientAuthenticationError as ex: |
| 163 | + logger.info("Azure CLI credential failed to authenticate: %s", str(ex)) |
| 164 | + # Check if the error is related to tenant ID |
| 165 | + if "Tenant" not in str(ex).lower(): |
| 166 | + raise # re-raise if it's a different error |
| 167 | + logger.info("Creating Azure CLI credential without tenant_id") |
| 168 | + cred = AzureCliCredential() |
| 169 | + cred.get_token("https://management.azure.com/.default") |
| 170 | + return cred |
156 | 171 |
|
157 | 172 |
|
158 | 173 | def _build_msi_client( |
159 | 174 | tenant_id: str | None = None, |
160 | | - aad_uri: str | None = None, |
161 | 175 | client_id: str | None = None, |
162 | 176 | **kwargs, |
163 | 177 | ) -> ManagedIdentityCredential: |
164 | 178 | """Build a credential from Managed Identity.""" |
165 | 179 | msi_kwargs: dict[str, Any] = kwargs.copy() |
166 | 180 | client_id = client_id or os.environ.get(AzureCredEnvNames.AZURE_CLIENT_ID) |
167 | 181 |
|
168 | | - return ManagedIdentityCredential( |
169 | | - tenant_id=tenant_id, |
170 | | - authority=aad_uri, |
171 | | - client_id=client_id, |
172 | | - **msi_kwargs, |
173 | | - ) |
| 182 | + try: |
| 183 | + cred = ManagedIdentityCredential(client_id=client_id) |
| 184 | + cred.get_token("https://management.azure.com/.default") |
| 185 | + return cred |
| 186 | + except ClientAuthenticationError as ex: |
| 187 | + logger.info( |
| 188 | + ( |
| 189 | + "Managed Identity credential failed to authenticate: %s, retrying with args " |
| 190 | + "tenant_id=%s, client_id=%s, kwargs=%s" |
| 191 | + ), |
| 192 | + str(ex), |
| 193 | + tenant_id, |
| 194 | + client_id, |
| 195 | + msi_kwargs, |
| 196 | + ) |
| 197 | + |
| 198 | + try: |
| 199 | + # Retry passing previous parameter set |
| 200 | + cred = ManagedIdentityCredential( |
| 201 | + client_id=client_id, tenant_id=tenant_id, **msi_kwargs |
| 202 | + ) |
| 203 | + cred.get_token("https://management.azure.com/.default") |
| 204 | + return cred |
| 205 | + except ClientAuthenticationError: |
| 206 | + # If we fail again, just create with no params |
| 207 | + logger.info( |
| 208 | + "Managed Identity credential failed auth - retrying with no params" |
| 209 | + ) |
| 210 | + return ManagedIdentityCredential() |
174 | 211 |
|
175 | 212 |
|
176 | 213 | def _build_vscode_client( |
@@ -380,7 +417,8 @@ def _az_connect_core( |
380 | 417 | # Create the wrapped credential using the passed credential |
381 | 418 | wrapped_credentials = CredentialWrapper(credential, resource_id=az_config.token_uri) |
382 | 419 | return AzCredentials( |
383 | | - wrapped_credentials, ChainedTokenCredential(credential) # type: ignore[arg-type] |
| 420 | + wrapped_credentials, # type: ignore[arg-type] |
| 421 | + ChainedTokenCredential(credential), # type: ignore[arg-type] |
384 | 422 | ) |
385 | 423 |
|
386 | 424 |
|
|
0 commit comments