Skip to content

Commit 26aedf7

Browse files
authored
[Identity] Emit warning in EnvironmentCredential for user/pass (#40595)
If UsernamePasswordCredential environment variables are detected in EnvironmentCredential, a warning noting its deprecation is emitted. Signed-off-by: Paul Van Eck <[email protected]>
1 parent da09607 commit 26aedf7

File tree

4 files changed

+40
-8
lines changed

4 files changed

+40
-8
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
import logging
66
import os
77
from typing import Optional, Union, Any, cast
8+
import warnings
89
from azure.core.credentials import AccessToken, AccessTokenInfo, TokenRequestOptions, SupportsTokenInfo
910

1011
from .. import CredentialUnavailableError
1112
from .._constants import EnvironmentVariables
13+
from .._internal import within_dac
1214
from .._internal.decorators import log_get_token
1315
from .certificate import CertificateCredential
1416
from .client_secret import ClientSecretCredential
@@ -96,8 +98,16 @@ def __init__(self, **kwargs: Any) -> None:
9698
username=os.environ[EnvironmentVariables.AZURE_USERNAME],
9799
password=os.environ[EnvironmentVariables.AZURE_PASSWORD],
98100
tenant_id=os.environ.get(EnvironmentVariables.AZURE_TENANT_ID), # optional for username/password auth
101+
_silence_deprecation_warning=True, # avoid duplicate warning
99102
**kwargs
100103
)
104+
warnings.warn(
105+
"Environment is configured to use username and password authentication. "
106+
"This authentication method is deprecated, as it doesn't support multifactor authentication (MFA). "
107+
"For more details, see https://aka.ms/azsdk/identity/mfa.",
108+
DeprecationWarning,
109+
stacklevel=3 if within_dac.get() else 2,
110+
)
101111

102112
if self._credential:
103113
_LOGGER.info("Environment is configured for %s", self._credential.__class__.__name__)

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,16 @@ class UsernamePasswordCredential(InteractiveCredential):
6363
"""
6464

6565
def __init__(self, client_id: str, username: str, password: str, **kwargs: Any) -> None:
66-
warnings.warn(
67-
f"{self.__class__.__name__} is deprecated, as is it doesn't support multifactor "
68-
"authentication (MFA). For more details, see https://aka.ms/azsdk/identity/mfa.",
69-
category=DeprecationWarning,
70-
stacklevel=2,
71-
)
66+
if not kwargs.pop("_silence_deprecation_warning", False):
67+
# Only emit the deprecation warning if the credential was constructed directly and not via
68+
# EnvironmentCredential since EnvironmentCredential will emit its own deprecation
69+
# warning if it is used to create a UsernamePasswordCredential.
70+
warnings.warn(
71+
f"{self.__class__.__name__} is deprecated, as it doesn't support multifactor "
72+
"authentication (MFA). For more details, see https://aka.ms/azsdk/identity/mfa.",
73+
category=DeprecationWarning,
74+
stacklevel=2,
75+
)
7276
# The base class will accept an AuthenticationRecord, allowing this credential to authenticate silently the
7377
# first time it's asked for a token. However, we want to ensure this first authentication is not silent, to
7478
# validate the given password. This class therefore doesn't document the authentication_record argument, and we

sdk/identity/azure-identity/azure/identity/aio/_credentials/environment.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
class EnvironmentCredential(AsyncContextManager):
2222
"""A credential configured by environment variables.
2323
24-
This credential is capable of authenticating as a service principal using a client secret or a certificate, or as
25-
a user with a username and password. Configuration is attempted in this order, using these environment variables:
24+
This credential is capable of authenticating as a service principal using a client secret or a certificate.
25+
Configuration is attempted in this order, using these environment variables:
2626
2727
Service principal with secret:
2828
- **AZURE_TENANT_ID**: ID of the service principal's tenant. Also called its 'directory' ID.

sdk/identity/azure-identity/tests/test_environment_credential.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,21 @@ def test_username_password_configuration():
175175
assert kwargs["password"] == password
176176
assert kwargs["tenant_id"] == tenant_id
177177
assert kwargs["foo"] == bar
178+
179+
180+
def test_username_password_deprecation_warning():
181+
"""the credential should pass expected values and any keyword arguments to its inner credential"""
182+
183+
client_id = "client-id"
184+
username = "username"
185+
password = "password"
186+
environment = {
187+
EnvironmentVariables.AZURE_CLIENT_ID: client_id,
188+
EnvironmentVariables.AZURE_USERNAME: username,
189+
EnvironmentVariables.AZURE_PASSWORD: password,
190+
}
191+
192+
with mock.patch.dict("os.environ", environment, clear=True):
193+
# the deprecation warning is only raised when the credential is used
194+
with pytest.deprecated_call():
195+
EnvironmentCredential()

0 commit comments

Comments
 (0)