From 725cb79253247221b7e044903333e8ae908ab0ae Mon Sep 17 00:00:00 2001 From: Paul Van Eck Date: Tue, 18 Feb 2025 22:50:52 +0000 Subject: [PATCH 1/3] [Identity] Deprecate UsernamePasswordCredential Multifactor authentication will be required on Azure, and this credential doesn't support MFA. Phasing this out. Signed-off-by: Paul Van Eck --- sdk/identity/azure-identity/CHANGELOG.md | 2 ++ sdk/identity/azure-identity/README.md | 4 +++- sdk/identity/azure-identity/TOKEN_CACHING.md | 4 ++-- .../azure/identity/_credentials/user_password.py | 7 +++++++ .../tests/test_username_password_credential.py | 5 +++++ 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/sdk/identity/azure-identity/CHANGELOG.md b/sdk/identity/azure-identity/CHANGELOG.md index 0938051e2af0..bc43745c1d7f 100644 --- a/sdk/identity/azure-identity/CHANGELOG.md +++ b/sdk/identity/azure-identity/CHANGELOG.md @@ -10,6 +10,8 @@ ### Other Changes +- Deprecated `UsernamePasswordCredential`. This credential does not support multifactor authentication (MFA) which is required by Microsoft Entra ID for most authentication scenarios. ([#39785](https://github.com/Azure/azure-sdk-for-python/pull/39785)) + ## 1.20.0 (2025-02-11) ### Features Added diff --git a/sdk/identity/azure-identity/README.md b/sdk/identity/azure-identity/README.md index c0d00fc0b975..9299baf4f93b 100644 --- a/sdk/identity/azure-identity/README.md +++ b/sdk/identity/azure-identity/README.md @@ -269,7 +269,7 @@ Not all credentials require this configuration. Credentials that authenticate th |[`DeviceCodeCredential`][device_code_cred_ref]| Interactively authenticates a user on devices with limited UI. | [Device code authentication](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-device-code)| |[`InteractiveBrowserCredential`][interactive_cred_ref]| Interactively authenticates a user with the default system browser. | [OAuth2 authentication code](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-auth-code-flow)| `InteractiveBrowserCredential` doesn't support GitHub Codespaces. As a workaround, use [`DeviceCodeCredential`][device_code_cred_ref]. |[`OnBehalfOfCredential`][obo_cred_ref]| Propagates the delegated user identity and permissions through the request chain. | [On-behalf-of authentication](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-on-behalf-of-flow)| -|[`UsernamePasswordCredential`][userpass_cred_ref]| Authenticates a user with a username and password (doesn't support multifactor authentication). | [Username + password authentication](https://learn.microsoft.com/entra/identity-platform/v2-oauth-ropc)| +|[`UsernamePasswordCredential`][userpass_cred_ref]| **Deprecated** - Authenticates a user with a username and password (doesn't support multifactor authentication). | [Username + password authentication](https://learn.microsoft.com/entra/identity-platform/v2-oauth-ropc)| ### Authenticate via development tools @@ -305,6 +305,8 @@ variables: ### Username and password +> **Warning**: Username and password authentication doesn't support multifactor authentication and is **deprecated**. + |Variable name|Value |-|- |`AZURE_CLIENT_ID`|ID of a Microsoft Entra application diff --git a/sdk/identity/azure-identity/TOKEN_CACHING.md b/sdk/identity/azure-identity/TOKEN_CACHING.md index 94517f1bc5da..09f975b30758 100644 --- a/sdk/identity/azure-identity/TOKEN_CACHING.md +++ b/sdk/identity/azure-identity/TOKEN_CACHING.md @@ -52,7 +52,7 @@ ClientSecretCredential( #### Persist user authentication record -When authenticating a user via `InteractiveBrowserCredential`, `DeviceCodeCredential`, or `UsernamePasswordCredential`, an `AuthenticationRecord` can be persisted as well. The authentication record is: +When authenticating a user via `InteractiveBrowserCredential` or `DeviceCodeCredential`, an `AuthenticationRecord` can be persisted as well. The authentication record is: - Returned from the `authenticate` API and contains data identifying an authenticated account. - Needed to identify the appropriate entry in the persisted token cache to silently authenticate on subsequent executions. @@ -68,7 +68,7 @@ record_json = record.serialize() #### Silently authenticating a user with AuthenticationRecord and TokenCachePersistenceOptions -Once an app has configured an `InteractiveBrowserCredential`, `DeviceCodeCredential`, or `UsernamePasswordCredential` to persist token data and an `AuthenticationRecord`, it's possible to silently authenticate. This example demonstrates an app setting the `TokenCachePersistenceOptions` and retrieving an `AuthenticationRecord` from the local file system to create an `InteractiveBrowserCredential` capable of silent authentication: +Once an app has configured an `InteractiveBrowserCredential` or `DeviceCodeCredential`, to persist token data and an `AuthenticationRecord`, it's possible to silently authenticate. This example demonstrates an app setting the `TokenCachePersistenceOptions` and retrieving an `AuthenticationRecord` from the local file system to create an `InteractiveBrowserCredential` capable of silent authentication: ```python deserialized_record = AuthenticationRecord.deserialize(record_json) diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/user_password.py b/sdk/identity/azure-identity/azure/identity/_credentials/user_password.py index 5ca7a3efc418..7a0d5a454650 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/user_password.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/user_password.py @@ -3,6 +3,7 @@ # Licensed under the MIT License. # ------------------------------------ from typing import Any, Dict +import warnings from .._internal import InteractiveCredential, wrap_exceptions @@ -59,6 +60,12 @@ class UsernamePasswordCredential(InteractiveCredential): """ def __init__(self, client_id: str, username: str, password: str, **kwargs: Any) -> None: + warnings.warn( + f"{self.__class__.__name__} is deprecated. Please use a more secure credential. See " + "https://aka.ms/azsdk/identity/mfa for details.", + category=DeprecationWarning, + stacklevel=2, + ) # The base class will accept an AuthenticationRecord, allowing this credential to authenticate silently the # first time it's asked for a token. However, we want to ensure this first authentication is not silent, to # validate the given password. This class therefore doesn't document the authentication_record argument, and we diff --git a/sdk/identity/azure-identity/tests/test_username_password_credential.py b/sdk/identity/azure-identity/tests/test_username_password_credential.py index 3ce95488fc3b..dcf7b847957c 100644 --- a/sdk/identity/azure-identity/tests/test_username_password_credential.py +++ b/sdk/identity/azure-identity/tests/test_username_password_credential.py @@ -229,3 +229,8 @@ def test_claims_challenge(get_token_method): assert msal_app.acquire_token_silent_with_error.call_count == 1 args, kwargs = msal_app.acquire_token_silent_with_error.call_args assert kwargs["claims_challenge"] == expected_claims + + +def test_deprecation_warning(): + with pytest.deprecated_call(): + UsernamePasswordCredential("client-id", "username", "password") From 5e225096fe1227fafa9df2f4a4eca074ae65c59e Mon Sep 17 00:00:00 2001 From: Paul Van Eck Date: Wed, 19 Feb 2025 22:58:50 +0000 Subject: [PATCH 2/3] Updates Signed-off-by: Paul Van Eck --- sdk/identity/azure-identity/CHANGELOG.md | 2 +- sdk/identity/azure-identity/README.md | 2 +- .../azure/identity/_credentials/environment.py | 3 +++ .../azure/identity/_credentials/user_password.py | 7 +++++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/sdk/identity/azure-identity/CHANGELOG.md b/sdk/identity/azure-identity/CHANGELOG.md index bc43745c1d7f..8de6ce58fab1 100644 --- a/sdk/identity/azure-identity/CHANGELOG.md +++ b/sdk/identity/azure-identity/CHANGELOG.md @@ -10,7 +10,7 @@ ### Other Changes -- Deprecated `UsernamePasswordCredential`. This credential does not support multifactor authentication (MFA) which is required by Microsoft Entra ID for most authentication scenarios. ([#39785](https://github.com/Azure/azure-sdk-for-python/pull/39785)) +- Deprecated `UsernamePasswordCredential`, as it doesn't support multifactor authentication (MFA). MFA will soon be enforced on all Microsoft Entra tenants. For more details, see [Planning for mandatory multifactor authentication](https://aka.ms/mfaforazure). ([#39785](https://github.com/Azure/azure-sdk-for-python/pull/39785)) ## 1.20.0 (2025-02-11) diff --git a/sdk/identity/azure-identity/README.md b/sdk/identity/azure-identity/README.md index 9299baf4f93b..f8fe79393c77 100644 --- a/sdk/identity/azure-identity/README.md +++ b/sdk/identity/azure-identity/README.md @@ -305,7 +305,7 @@ variables: ### Username and password -> **Warning**: Username and password authentication doesn't support multifactor authentication and is **deprecated**. +> **Warning**: Username and password authentication doesn't support multifactor authentication and is **deprecated**. For more details, see [Planning for mandatory multifactor authentication](https://aka.ms/azsdk/identity/mfa). |Variable name|Value |-|- diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py index 8f87a1d9ff97..d11fd00c1c68 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/environment.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/environment.py @@ -46,6 +46,9 @@ class EnvironmentCredential: when no value is given. User with username and password: + **Deprecated**: Username and password authentication doesn't support multifactor authentication (MFA). + For more details on Microsoft Entra MFA enforcement, see https://aka.ms/azsdk/identity/mfa. + - **AZURE_CLIENT_ID**: the application's client ID - **AZURE_USERNAME**: a username (usually an email address) - **AZURE_PASSWORD**: that user's password diff --git a/sdk/identity/azure-identity/azure/identity/_credentials/user_password.py b/sdk/identity/azure-identity/azure/identity/_credentials/user_password.py index 7a0d5a454650..cee3ad825766 100644 --- a/sdk/identity/azure-identity/azure/identity/_credentials/user_password.py +++ b/sdk/identity/azure-identity/azure/identity/_credentials/user_password.py @@ -11,6 +11,9 @@ class UsernamePasswordCredential(InteractiveCredential): """Authenticates a user with a username and password. + **Deprecated**: This credential doesn't support multifactor authentication (MFA). + For more details on Microsoft Entra MFA enforcement, see https://aka.ms/azsdk/identity/mfa. + In general, Microsoft doesn't recommend this kind of authentication, because it's less secure than other authentication flows. @@ -61,8 +64,8 @@ class UsernamePasswordCredential(InteractiveCredential): def __init__(self, client_id: str, username: str, password: str, **kwargs: Any) -> None: warnings.warn( - f"{self.__class__.__name__} is deprecated. Please use a more secure credential. See " - "https://aka.ms/azsdk/identity/mfa for details.", + f"{self.__class__.__name__} is deprecated, as is it doesn't support multifactor " + "authentication (MFA). For more details, see https://aka.ms/azsdk/identity/mfa.", category=DeprecationWarning, stacklevel=2, ) From dd96b192a6bbd88443c20eaca9a8dc3749f6f781 Mon Sep 17 00:00:00 2001 From: Paul Van Eck Date: Thu, 20 Feb 2025 19:03:00 +0000 Subject: [PATCH 3/3] Review feedback udpates Signed-off-by: Paul Van Eck --- sdk/identity/azure-identity/CHANGELOG.md | 2 +- sdk/identity/azure-identity/README.md | 2 +- sdk/identity/azure-identity/TOKEN_CACHING.md | 1 - .../azure-identity/samples/azure-aad-auth-with-redis-py.md | 5 ++--- 4 files changed, 4 insertions(+), 6 deletions(-) diff --git a/sdk/identity/azure-identity/CHANGELOG.md b/sdk/identity/azure-identity/CHANGELOG.md index 8de6ce58fab1..0b4cef2c0278 100644 --- a/sdk/identity/azure-identity/CHANGELOG.md +++ b/sdk/identity/azure-identity/CHANGELOG.md @@ -10,7 +10,7 @@ ### Other Changes -- Deprecated `UsernamePasswordCredential`, as it doesn't support multifactor authentication (MFA). MFA will soon be enforced on all Microsoft Entra tenants. For more details, see [Planning for mandatory multifactor authentication](https://aka.ms/mfaforazure). ([#39785](https://github.com/Azure/azure-sdk-for-python/pull/39785)) +- Deprecated `UsernamePasswordCredential`, as it doesn't support multifactor authentication (MFA). MFA will soon be enforced on all Microsoft Entra tenants. For more details, see [Planning for mandatory MFA](https://aka.ms/mfaforazure). ([#39785](https://github.com/Azure/azure-sdk-for-python/pull/39785)) ## 1.20.0 (2025-02-11) diff --git a/sdk/identity/azure-identity/README.md b/sdk/identity/azure-identity/README.md index f8fe79393c77..0a2bc7419965 100644 --- a/sdk/identity/azure-identity/README.md +++ b/sdk/identity/azure-identity/README.md @@ -305,7 +305,7 @@ variables: ### Username and password -> **Warning**: Username and password authentication doesn't support multifactor authentication and is **deprecated**. For more details, see [Planning for mandatory multifactor authentication](https://aka.ms/azsdk/identity/mfa). +> **Warning**: Username and password authentication doesn't support multifactor authentication (MFA) and is **deprecated**. For more details, see [Planning for mandatory MFA](https://aka.ms/azsdk/identity/mfa). |Variable name|Value |-|- diff --git a/sdk/identity/azure-identity/TOKEN_CACHING.md b/sdk/identity/azure-identity/TOKEN_CACHING.md index 09f975b30758..a47ecf03039a 100644 --- a/sdk/identity/azure-identity/TOKEN_CACHING.md +++ b/sdk/identity/azure-identity/TOKEN_CACHING.md @@ -101,5 +101,4 @@ The following table indicates the state of in-memory and persistent caching in e | `InteractiveBrowserCredential` | Supported | Supported | | `ManagedIdentityCredential` | Supported | Not Supported | | `OnBehalfOfCredential` | Supported | Supported | -| `UsernamePasswordCredential` | Supported | Supported | | `WorkloadIdentityCredential` | Supported | Not Supported | diff --git a/sdk/identity/azure-identity/samples/azure-aad-auth-with-redis-py.md b/sdk/identity/azure-identity/samples/azure-aad-auth-with-redis-py.md index 29baed01f08d..703a7cc37298 100644 --- a/sdk/identity/azure-identity/samples/azure-aad-auth-with-redis-py.md +++ b/sdk/identity/azure-identity/samples/azure-aad-auth-with-redis-py.md @@ -82,7 +82,6 @@ if __name__ == '__main__': - [Client Certificate Credential](https://aka.ms/azsdk/python/identity/certificatecredential) - [Client Secret Credential](https://aka.ms/azsdk/python/identity/clientsecretcredential) - [Managed Identity Credential](https://aka.ms/azsdk/python/identity/managedidentitycredential) -- [Username Password Credential](https://aka.ms/azsdk/python/identity/usernamepasswordcredential) - [Azure CLI Credential](https://aka.ms/azsdk/python/identity/azclicredential) - [Interactive Browser Credential](https://aka.ms/azsdk/python/identity/interactivebrowsercredential) - [Device Code Credential](https://aka.ms/azsdk/python/identity/devicecodecredential) @@ -188,7 +187,7 @@ To mitigate this error, navigate to your Azure Cache for Redis resource in the A ##### Managed Identity not working from Local Development Machine -Managed identity does not work from a local development machine. To use managed identity, your code must be running -in an Azure VM (or another type of resource in Azure). To run locally with Entra ID authentication, you'll need to +Managed identity does not work from a local development machine. To use managed identity, your code must be running +in an Azure VM (or another type of resource in Azure). To run locally with Entra ID authentication, you'll need to use a service principal or user account. This is a common source of confusion, so ensure that when developing locally, you configure your application to use a service principal or user credentials for authentication.