From d9493a13f71557f461451e45508033b8810dd588 Mon Sep 17 00:00:00 2001 From: Sherman Ouko <12745944+SHERMANOUKO@users.noreply.github.com> Date: Thu, 29 Feb 2024 19:26:54 +0300 Subject: [PATCH 01/15] Update overview documentation --- msal-python-conceptual/index.md | 127 +++++++++++++++----------------- 1 file changed, 60 insertions(+), 67 deletions(-) diff --git a/msal-python-conceptual/index.md b/msal-python-conceptual/index.md index 03a21d6..bc0f2bf 100644 --- a/msal-python-conceptual/index.md +++ b/msal-python-conceptual/index.md @@ -1,22 +1,20 @@ --- title: Overview of the Microsoft Authentication Library (MSAL) for Python description: Get started with the Microsoft Authentication Library for Python to sign in users or apps with Microsoft identities." -author: Dickson-Mwendia +author: SHERMANOUKO manager: CelesteDG ms.service: msal ms.subservice: msal-python ms.topic: conceptual -ms.date: 02/07/2024 -ms.author: dmwendia -ms.reviewer: shermanouko, rayluo +ms.date: 02/29/2024 +ms.author: shermanouko +ms.reviewer: dmwendia, rayluo --- # Microsoft Authentication Library (MSAL) for Python -The Microsoft Authentication Library (MSAL) for Python library enables you to sign in users or apps with Microsoft identities ([Microsoft Entra ID](https://azure.microsoft.com/services/active-directory/), [Microsoft Accounts](https://account.microsoft.com), and [Azure AD B2C](https://azure.microsoft.com/services/active-directory-b2c/) accounts). Using MSAL Python, you can acquire tokens from Microsoft Entra ID to call protected web APIs such as [Microsoft Graph](https://graph.microsoft.io/), other Microsoft APIs, or your own APIs. - - +The Microsoft Authentication Library (MSAL) for Python library enables you to sign in users or apps with Microsoft identities. These identities include work and school accounts, personal microsoft accounts, social accounts, customer accounts and so on. Using MSAL Python, you can acquire tokens from Microsoft Entra to call protected web APIs such as [Microsoft Graph](https://graph.microsoft.io/), other Microsoft APIs, or your own APIs. MSAL Python supports a variety of application types, including public client applications (desktop and mobile) and confidential client applications (web apps, web APIs, and daemon applications). ## Prerequisites @@ -31,22 +29,36 @@ Install the MSAL for Python package. You can find MSAL Python on [PyPI](https:// pip install msal ``` -## Setting up +## Identity concepts + +MSAL Python is part of the [Microsoft identity platform](/entra/identity-platform/v2-overview) ecosystem. It's important to farmiliarize yourself with the following concepts to effectively use MSAL Python to protect your applications and APIs: + +- [Identity and access management](/entra/fundamentals/identity-fundamental-concepts) +- [Authentication and authorization](/entra/identity-platform/authentication-vs-authorization) +- [OAuth 2.0 and OpenID Connect (OIDC) in the Microsoft identity platform](/entra/identity-platform/v2-protocols) +- [Confidential and public client accounts in the Microsoft identity platform](/entra/identity-platform/msal-client-applications) +- [Security tokens](/entra/identity-platform/security-tokens) + +## Usage scenarios -Before using MSAL Python, make sure to [register your application](/azure/active-directory/develop/quickstart-v2-register-an-app) with the Microsoft identity platform. You will need to take note of your **client ID** and **tenant ID**. +To use MSAL Python, register an application with the Microsoft identity platform. You'll need an Azure account with an active subscription. [Create a free account](https://signup.azure.com/) if you don't have one. You can register your app in a [customer tenant](/entra/external-id/customers/quickstart-tenant-setup) or [workforce tenant](/entra/identity-platform/scenario-web-app-sign-user-app-registration?tabs=python). ->[!IMPORTANT] ->When registering the application, make sure that you set up **redirect URLs** within the **Authentication** blade. Redirect URLs vary depending on the target platform. -> ->![Screenshot showing redirect URLs in Azure Portal](./media/redirect-urls.png) -> ->For desktop and mobile applications, make sure you add `http://localhost` as redirect URL if you do not rely on authentication brokers. +MSAL Python can be used by applications to acquire tokens to access protected APIs. Tokens can be acquired by different **application types**. These app types include desktop applications, web applications, web APIs, and applications running on devices that don't have a browser (such as IoT devices). Different app types follow different auth flows. + +In MSAL Python, applications are categorized as follows: + +- [Public client applications](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1) (desktop and mobile). These types of apps cannot store app secrets securely. +- [Confidential client applications](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1) (web apps, web APIs, and daemon applications). These type of apps securely store a secret registered with Microsoft Entra ID. + +For more information, see the documentation on [public client and confidential client apps](/entra/identity-platform/msal-client-applications) and the [different app types and their auth flows](/entra/identity-platform/authentication-flows-app-scenarios) in the Microsoft identity platform. + +After determining whether your application is a public or confidential client application, you can use MSAL Python to acquire tokens for different scenarios. ## Basic usage Acquiring tokens with MSAL Python follows a three-step pattern. There will be some variations for different flows. If you would like to see them in action, download our [samples](https://github.com/AzureAD/microsoft-authentication-library-for-python/tree/dev/sample). -1. MSAL relies on a clean separation between [public client and confidential client applications](https://tools.ietf.org/html/rfc6749#section-2.1). Therefore, create either a [`PublicClientApplication`](xref:msal.application.PublicClientApplication) or a [`ConfidentialClientApplication`](xref:msal.application.ConfidentialClientApplication) instance and reuse it during the lifecycle of your application. For example, for a public client application, the initalization code might look like this: +1. MSAL relies on a clean separation between public client and confidential client applications. Therefore, create either a [*PublicClientApplication*](xref:msal.application.PublicClientApplication) or a [*ConfidentialClientApplication*](xref:msal.application.ConfidentialClientApplication) instance and reuse it during the lifecycle of your application. For example, for a public client application, the initialization code might look like this: ```python from msal import PublicClientApplication @@ -56,33 +68,29 @@ Acquiring tokens with MSAL Python follows a three-step pattern. There will be so authority="https://login.microsoftonline.com/common") ``` - >[!NOTE] - >The authority is set to `/common` to allow sign ins with both organizaiton and personal Microsoft accounts. You can change it to `/organizations` to only allow sign ins with work and school accounts, `/consumers` to only allow personal Microsoft accounts, or with `/YOUR_TENANT_ID` to only allow sign ins from work and school accounts associated with your tenant. + The authority value varies depending on the type of accounts you are signing-in and the kind of tenant your app is registered in. For example, to sign-in both work and personal Microsoft accounts provisioned in workforce tenants (Microsoft Entra ID) you would use `https://login.microsoftonline.com/c/common`. For customer accounts provisioned in customer tenants, your authority will take a form like `https://.ciamlogin.com`. For more information, see [token issuer documentation](/entra/identity-platform/access-tokens#validate-the-issuer). - Instantiate a variable to hold the authentication result: +1. Try and obtain the tokens from the cache first. The API model in MSAL provides you explicit control on how to utilize the token cache. While the caching part is technically optional, we highly recommend you to use it in your application. Using the cache you can ensure that you're not making any extra API calls and handle the token refresh automatically. ```python - result = None # It is just an initial value. Please follow instructions below. + # initialize result variable to hole the token response + result = None + + # We now check the cache to see + # whether we already have some accounts that the end user already used to sign in before. + accounts = app.get_accounts() + if accounts: + # If so, you could then somehow display these accounts and let end user choose + print("Pick the account you want to use to proceed:") + for a in accounts: + print(a["username"]) + # Assuming the end user chose this one + chosen = accounts[0] + # Now let's try to find a token in cache for this account + result = app.acquire_token_silent(["User.Read"], account=chosen) ``` -2. Try and obtain the tokens from the cache first. The API model in MSAL provides you explicit control on how to utilize the token cache. While the caching part is technically optional, we highly recommend you to use it in your application. Using the cache you can ensure that you're not making any extra API calls and handle the token refresh automatically. - - ```python - # We now check the cache to see - # whether we already have some accounts that the end user already used to sign in before. - accounts = app.get_accounts() - if accounts: - # If so, you could then somehow display these accounts and let end user choose - print("Pick the account you want to use to proceed:") - for a in accounts: - print(a["username"]) - # Assuming the end user chose this one - chosen = accounts[0] - # Now let's try to find a token in cache for this account - result = app.acquire_token_silent(["User.Read"], account=chosen) - ``` - -3. If there is no suitable token in the cache or you've chosen to skip the previous step, send a request to Microsoft Entra ID to get a token. There are different methods based on your client type and scenario, but for the purposes of the example we're showing how to use [`acquire_token_interactive`](xref:msal.application.PublicClientApplication.acquire_token_interactive) which will prompt the user to provide their credentials. +1. If there is no suitable token in the cache or you've chosen to skip the previous step, send a request to Microsoft Entra ID to get a token. There are different methods based on your client type and scenario, but for the purposes of the example we're showing how to use [`acquire_token_interactive`](xref:msal.application.PublicClientApplication.acquire_token_interactive) which will prompt the user to provide their credentials. ```python if not result: @@ -96,41 +104,26 @@ Acquiring tokens with MSAL Python follows a three-step pattern. There will be so print(result.get("correlation_id")) # You may need this when reporting a bug ``` -4. Save the code into a Python file locally, such as `msaltest.py`. -5. Run the code by executing `python .\msalpytest.py`. - ->[!NOTE] ->You can also download runnable samples from the [library repository](https://github.com/AzureAD/microsoft-authentication-library-for-python/blob/1.22.0/sample/interactive_sample.py). - -If the application was configured correctly, you should see a web browser window appear asking the user to sign in. - -![Example of an app prompting the user to sign in with their account](./media/basic-pca-app-prompt.gif) - -Once the authentication is completed and you closed the browser, you should be able to see the access token printed in the terminal. - -## Usage scenarios - -MSAL Python can be used by applications to acquire tokens to access protected APIs. Tokens can be acquired by different **application types**: desktop applications, web applications, web APIs, and applications running on devices that don't have a browser (such as IoT devices). In MSAL Python, applications are categorized as follows: +1. Save the code into a Python file locally, such as `msaltest.py`. +1. Run the code by executing `python .\msalpytest.py`. The following visual shows the sign-in experience for this example. -- **Public client applications (desktop and mobile)**. These types of apps cannot store app secrets securely. -- **Confidential client applications (web apps, web APIs, and daemon applications)**. These type of apps securely store a secret registered with Microsoft Entra ID. + ![Example of an app prompting the user to sign in with their account](./media/basic-pca-app-prompt.gif) -Learn more about instantiating and configuring the above in the [Client applications](./getting-started/client-applications.md) topic. +1. Once the authentication is completed and you closed the browser, you should be able to see the access token printed in the terminal. -MSAL Python supports acquiring tokens either in the name of a user or in the name of the application itself (without a user). In the latter case, a confidential client application must be used. +## Samples -MSAL Python can be used in applications running on different operating systems (Windows, Linux, macOS). +TRhere are several samples you can use to get started with MSAL Python. -Key scenarios supported by MSAL Python: +- Samples from the [library repository](https://github.com/AzureAD/microsoft-authentication-library-for-python/blob/1.22.0/sample/interactive_sample.py). +- A single repository with [samples used in our documentation](https://github.com/Azure-Samples/ms-identity-docs-code-python). These samples have supporting documentation to help you build and replicate them from scratch. -- [Web application that signs in users](/azure/active-directory/develop/scenario-web-app-sign-user-overview) -- [Web Application signing in a user and calling a Web API in the name of the user](/azure/active-directory/develop/scenario-web-app-call-api-overview) (note that MSAL only helps the web application to sign in and obtain tokens. To [protect a web API](/azure/active-directory/develop/scenario-protected-web-api-overview), you will need other libraries). -- [Desktop application calling a Web API in the name of the signed-in user](/azure/active-directory/develop/scenario-desktop-overview) -- [Desktop/service daemon application calling Web API without a user](/azure/active-directory/develop/scenario-daemon-overview) -- [Application without a browser, or IOT application calling an API in the name of the user](/azure/active-directory/develop/scenario-desktop-acquire-token?tabs=python#command-line-tool-without-web-browser) +## References -Can't find the scenario you are looking for? Check out the [supported scenarios and platforms](/azure/active-directory/develop/authentication-flows-app-scenarios#scenarios-and-supported-platforms-and-languages) across MSAL libraries. +- MSAL Python library repository on [GitHub](ttps://github.com/AzureAD/microsoft-authentication-library-for-pytho) +- [MSAL Python releases on GitHub](https://github.com/AzureAD/microsoft-authentication-library-for-python/releases). -## Releases +## See also -Refer to [MSAL Python releases on GitHub](https://github.com/AzureAD/microsoft-authentication-library-for-python/releases). +- [Instantiate your application](./getting-started/client-applications.md) using MSAL Python +- [Acquire tokens](./getting-started/acquire_token.md) using MSAL Python From 1730b3805ee521263670205c9c6d3061842a3eae Mon Sep 17 00:00:00 2001 From: Sherman Ouko <12745944+SHERMANOUKO@users.noreply.github.com> Date: Thu, 29 Feb 2024 19:30:37 +0300 Subject: [PATCH 02/15] Update overview documentation --- msal-python-conceptual/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msal-python-conceptual/index.md b/msal-python-conceptual/index.md index bc0f2bf..598080b 100644 --- a/msal-python-conceptual/index.md +++ b/msal-python-conceptual/index.md @@ -120,10 +120,10 @@ TRhere are several samples you can use to get started with MSAL Python. ## References -- MSAL Python library repository on [GitHub](ttps://github.com/AzureAD/microsoft-authentication-library-for-pytho) +- MSAL Python library repository on [GitHub](https://github.com/AzureAD/microsoft-authentication-library-for-python) - [MSAL Python releases on GitHub](https://github.com/AzureAD/microsoft-authentication-library-for-python/releases). ## See also - [Instantiate your application](./getting-started/client-applications.md) using MSAL Python -- [Acquire tokens](./getting-started/acquire_token.md) using MSAL Python +- [Acquire tokens](./getting-started/acquiring-tokens.md) using MSAL Python From 614fc3e686b82e5be42309577ec743c7fde42cad Mon Sep 17 00:00:00 2001 From: Sherman Ouko <12745944+SHERMANOUKO@users.noreply.github.com> Date: Thu, 29 Feb 2024 19:58:13 +0300 Subject: [PATCH 03/15] Update overview documentation --- msal-python-conceptual/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msal-python-conceptual/index.md b/msal-python-conceptual/index.md index 598080b..73b08ec 100644 --- a/msal-python-conceptual/index.md +++ b/msal-python-conceptual/index.md @@ -43,7 +43,7 @@ MSAL Python is part of the [Microsoft identity platform](/entra/identity-platfor To use MSAL Python, register an application with the Microsoft identity platform. You'll need an Azure account with an active subscription. [Create a free account](https://signup.azure.com/) if you don't have one. You can register your app in a [customer tenant](/entra/external-id/customers/quickstart-tenant-setup) or [workforce tenant](/entra/identity-platform/scenario-web-app-sign-user-app-registration?tabs=python). -MSAL Python can be used by applications to acquire tokens to access protected APIs. Tokens can be acquired by different **application types**. These app types include desktop applications, web applications, web APIs, and applications running on devices that don't have a browser (such as IoT devices). Different app types follow different auth flows. +MSAL Python can be used by applications to acquire tokens to access protected APIs. Tokens can be acquired by different application types. These app types include desktop applications, web applications, web APIs, and applications running on devices that don't have a browser (such as IoT devices). Different app types follow different auth flows. In MSAL Python, applications are categorized as follows: @@ -68,7 +68,7 @@ Acquiring tokens with MSAL Python follows a three-step pattern. There will be so authority="https://login.microsoftonline.com/common") ``` - The authority value varies depending on the type of accounts you are signing-in and the kind of tenant your app is registered in. For example, to sign-in both work and personal Microsoft accounts provisioned in workforce tenants (Microsoft Entra ID) you would use `https://login.microsoftonline.com/c/common`. For customer accounts provisioned in customer tenants, your authority will take a form like `https://.ciamlogin.com`. For more information, see [token issuer documentation](/entra/identity-platform/access-tokens#validate-the-issuer). + The authority value varies depending on the type of accounts you are signing-in and the kind of tenant your app is registered in. For example, to sign-in both work and personal Microsoft accounts provisioned in workforce tenants (Microsoft Entra ID) you would use `https://login.microsoftonline.com/common`. For customer accounts provisioned in customer tenants, your authority will take a form like `https://.ciamlogin.com`. For more information, see [token issuer documentation](/entra/identity-platform/access-tokens#validate-the-issuer). 1. Try and obtain the tokens from the cache first. The API model in MSAL provides you explicit control on how to utilize the token cache. While the caching part is technically optional, we highly recommend you to use it in your application. Using the cache you can ensure that you're not making any extra API calls and handle the token refresh automatically. From 544b404423bf6cd92c78e5a49479e75b8432296c Mon Sep 17 00:00:00 2001 From: Sherman Ouko <12745944+SHERMANOUKO@users.noreply.github.com> Date: Thu, 29 Feb 2024 19:59:43 +0300 Subject: [PATCH 04/15] Update overview documentation --- msal-python-conceptual/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/index.md b/msal-python-conceptual/index.md index 73b08ec..4ec699c 100644 --- a/msal-python-conceptual/index.md +++ b/msal-python-conceptual/index.md @@ -121,7 +121,7 @@ TRhere are several samples you can use to get started with MSAL Python. ## References - MSAL Python library repository on [GitHub](https://github.com/AzureAD/microsoft-authentication-library-for-python) -- [MSAL Python releases on GitHub](https://github.com/AzureAD/microsoft-authentication-library-for-python/releases). +- MSAL Python releases on [GitHub](https://github.com/AzureAD/microsoft-authentication-library-for-python/releases). ## See also From 7cca31679420e2b6145c5367e5ead9e4044be6cb Mon Sep 17 00:00:00 2001 From: Sherman Ouko <12745944+SHERMANOUKO@users.noreply.github.com> Date: Wed, 6 Mar 2024 12:57:57 +0300 Subject: [PATCH 05/15] Update qcquire token documentation --- .../getting-started/acquiring-tokens.md | 216 ++++++++++++++++-- 1 file changed, 191 insertions(+), 25 deletions(-) diff --git a/msal-python-conceptual/getting-started/acquiring-tokens.md b/msal-python-conceptual/getting-started/acquiring-tokens.md index 7785feb..f538fed 100644 --- a/msal-python-conceptual/getting-started/acquiring-tokens.md +++ b/msal-python-conceptual/getting-started/acquiring-tokens.md @@ -1,57 +1,223 @@ --- title: Acquire tokens for your app description: Learn how to acquire tokens for your Python appliccation. You can acquire tokens silently or interactively through a web browser. -author: Dickson-Mwendia +author: SHERMANOUKO manager: CelesteDG ms.service: msal ms.subservice: msal-python ms.topic: conceptual -ms.date: 02/07/2024 -ms.author: dmwendia -ms.reviewer: shermanouko, rayluo -zone_pivot_groups: msal-python-acquire-token -zone_pivot_group_filename: msal/python/zone-pivot-groups.json +ms.date: 03/06/2024 +ms.author: shermanouko +ms.reviewer: dmwendia, rayluo +# zone_pivot_groups: msal-python-acquire-token +# zone_pivot_group_filename: msal/python/zone-pivot-groups.json --- -# Acquiring tokens +# Acquire tokens -As explained in [MSAL Python usage scenarios](../index.md#usage-scenarios), there are many ways of acquiring a token. Some require user interaction through a web browser, while others don't require any user interaction at all. +There are many ways of acquiring a token with MSAL Python. Some require user interaction while others don't. The approach used to acquire a token is different depending on whether the developer is building a public client (desktop or mobile) or a confidential client application (web app, web API, or daemon like a Windows service). ## Prerequisites -Before acquiring tokens with MSAL Python, make sure to instantiate a [client application](./client-applications.md) +Before you acquire tokens with MSAL Python, make sure learn how to instantiate a [client application](./client-applications.md). -## Token acquisition methods +## Get user account -The approach to acquiring a token is different depending on the application type - public client applications (desktop and mobile) or confidential client application (web app, web API, or a daemon application like a Windows service). Each of the individual approaches is described below. +An app can acquire a token as itself or on behalf of a user. To acquire a token on behalf of a user, the app needs to know the user's account. MSAL Python provides the [`get_accounts`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-get-accounts) method to get the user's account. This method is available on both [`PublicClientApplication`](/python/api/msal/msal.application.publicclientapplication) and [`ConfidentialClientApplication`](/python/api/msal/msal.application.confidentialclientapplication) classes. The method returns a list of accounts which you the user has previously signed in with, that is, exists in cache. +```python +accounts = app.get_accounts(username=user.get("preferred_username")) +``` -:::zone pivot="pca" +The account selected by the user for sign-in can later be used in `acquire_token_silent()` to find its tokens. -### Public client applications +## Token grant flows -Public client applications cannot securely store a secret and can _only_ authenticate the user that is interacting with the product. MSAL Python exposes most of the token acquisition logic for public applications through [`PublicClientApplication`](xref:msal.application.PublicClientApplication). Using this class enables developers to: +There are several authentication flows that can be used to acquire tokens with MSAL Python. You can find more information on these flows on the [Microsoft identity platform documentation](/entra/identity-platform/v2-oauth2-auth-code-flow). -- Acquire tokens **as the user** with the help of an [interactive flow](/azure/active-directory/develop/scenario-desktop-acquire-token?tabs=python#acquiring-a-token-interactively) after letting the user sign-in through the authorization request URL. -- It's also possible (but not recommended) to get a token with a [username and password](/azure/active-directory/develop/scenario-desktop-acquire-token?tabs=python#username--password). -- For applications running on devices which don't have a web browser, it's possible to acquire a token through the [device code flow](/azure/active-directory/develop/scenario-desktop-acquire-token?tabs=python#command-line-tool-without-web-browser), which provides the user with a URL and a code. The user goes to a web browser on another device, enters the code and signs in. On successful authentication, Microsoft Entra ID will return a token to the browser-less device. +> [!WARNING] +> Always use MSAL to handle to get security tokens and call protected web APIs in your apps. We don't recommend you implementing your own token acquisition logic. These flows are to help you have a better understanding of how things work. If you are securing a web application, we recommend using the [identity](https://pypi.org/project/identity/) library. This library is not officially maintained by Microsoft but it implements most of the logic you need to acquire tokens in web apps. -:::zone-end +## Interactive vs silent -:::zone pivot="cca" +MSAL Python supports both interactive and silent token acquisition. Interactive token acquisition requires user interaction, while silent token acquisition doesn't. Public clients generally require user interaction while confidential clients rely on pre-provisioned credentials, like certificates and secrets. -### Confidential client applications +Use the [`acquire_token_silent_with_error`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent-with-error) method to silently acquire a token. This method finds a valid access token from cache, or a valid refresh token from cache and then automatically use it to redeem a new access token. If neither is true, you'll need to use an interactive method to acquire the token. + +If your app doesn't care about the exact token refresh error during token cache look-up, then the [`acquire_token_silent`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent) method is recommended. + +An example usage of this method(s) is as shown in the following code snippet. + +```python +if accounts: + # If so, you could then somehow display these accounts and let end user choose + chosen = accounts[0] + result = app.acquire_token_silent(scopes=["your_scope"], account=chosen) + + # At this point, you can save you can update your cache if you are using token caching + # check result variable, if its None then you should interactively acquire a token + if not result: + # So no suitable token exists in cache. Let's get a new one from Microsoft Entra. + result = app.acquire_token_by_one_of_the_actual_method(..., scopes=["User.Read"]) + + if "access_token" in result: + access_token = result["access_token"] + else: + print(result.get("error")) + print(result.get("error_description")) + print(result.get("correlation_id")) # You may need this when reporting a bug +``` + +Several methods are available for interactive token acquisition. The method to use depends on the type of app you are building and the token grant flow applicable to your scenario. + +## Public clients interactive token acquisition + +Public client applications can't securely store a secret and can only authenticate the user that is interacting with the product. MSAL Python exposes most of the token acquisition logic for public applications through [`PublicClientApplication`](xref:msal.application.PublicClientApplication). Using this class enables developers to: + +### Device code flow + +For applications running on devices which don't have a web browser, it's possible to acquire a token through the [device code flow](/entra/identity-platform/v2-oauth2-device-code), which provides the user with a URL and a code. The user goes to a web browser on another device, enters the code and signs in. On successful authentication, Microsoft Entra will return a token to the browser-less device. + +First, you'll need to call the [`initiate_device_flow`](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-initiate-device-flow) method + +```python +flow = app.initiate_device_flow(scopes=config["scope"]) +if "user_code" not in flow: + raise ValueError( + "Fail to create device flow. Err: %s" % json.dumps(flow, indent=4)) + +print(flow["message"]) +sys.stdout.flush() # Some terminal needs this to ensure the message is shown + +# Ideally you should wait here, in order to save some unnecessary polling +# input("Press Enter after signing in from another device to proceed, CTRL+C to abort.") +``` + +You then pass the flow dictionary object to the [`acquire_token_by_device_flow`](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-by-device-flow) method to get the token. By default, this method will block the current thread. You can follow [these instructions](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_by_device_flow) to shorten the block time or you may even turn off the blocking behavior and then keep calling [`acquire_token_by_device_flow`](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-by-device-flow) in your own customized loop. + +```python +result = app.acquire_token_by_device_flow(flow) + +if "access_token" in result: + access_token = result["access_token"] +else: + print(result.get("error")) +``` + +A successful response a dictionary with an `access_token` key. + +### Acquire token interactive + +MSAL Python also offers the ability for public client apps (Desktops and Mobile) to acquire tokens as the user with the help of an interactive flow after letting the user sign-in through the authorization request URL via a web browser. You'll need to set the redirect URI of your app to `http://localhost` in the Microsoft Entra admin center for your app registration. If you opt in to use broker during `PublicClientApplication` creation, your app also needs `ms-appx-web://Microsoft.AAD.BrokerPlugin/YOUR_CLIENT_ID` as a redirect URI. + +```python +result = app.acquire_token_interactive( # It automatically provides PKCE protection + scopes=config["scope"]) + +if "access_token" in result: + access_token = result["access_token"] +else: + print(result.get("error")) +``` + +### Username and password + +It's also possible (but not recommended) to get a token with a [username and password](/entra/identity-platform/v2-oauth-ropc). MSAL Python provides the [`acquire_token_by_username_password`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-username-password) method for this use case. It's not recommended because the application will be asking a user for their password directly, which is an insecure pattern. + +```python +result = app.acquire_token_by_username_password( + username=config["username"], password=config["password"], scopes=config["scope"]) + +if "access_token" in result: + access_token = result["access_token"] +else: + print(result.get("error")) +``` + +## Confidential clients interactive token acquisition Confidential client applications can securely store a secret and can authenticate both on behalf of an application as well as on behalf of a given user. With MSAL Python, developers can use [`ConfidentialClientApplication`](xref:msal.application.ConfidentialClientApplication) to access confidential client application capabilities, such as: -- Acquire token **as the application itself** using [client credentials](/azure/active-directory/develop/scenario-daemon-acquire-token?tabs=python#acquiretokenforclient-api), and not for a user. For example, this can be used in applications which process users in batches and not one particular user, such as syncing tools. -- In the case of web Apps or web APIs **calling another downstream Web API in the name of the user**, use the [On Behalf Of flow](/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow) to acquire a token based on a user assertion (e.g., SAML, JWT). -- **For Web apps authenticating in the name of a user**, acquire tokens through [authorization code](/azure/active-directory/develop/scenario-web-app-call-api-acquire-token?tabs=python) after letting the user sign-in through the authorization request URL. This is typically the mechanism used by an application which lets the user sign-in using OpenID Connect but then wants to access Web APIs for this particular user. +### Acquire token for client + +Acquire token as the application itself using [client credentials](/entra/identity-platform/v2-oauth2-client-creds-grant-flow), and not for a user. For example, this can be used in applications which process users in batches and not one particular user, such as syncing tools. MSAL Python provides the [`acquire_token_for_client`](/python/api/msal/msal.application.confidentialclientapplication#msal-application-confidentialclientapplication-acquire-token-for-client) method to do this. Since MSAL Python 1.23, this method will automatically look for token from cache, and only send request to Identity Provider when cache misses. + +```python +result = app.acquire_token_for_client(scopes=config["scope"]) + +if "access_token" in result: + access_token = result["access_token"] +else: + print(result.get("error")) +``` + +### Acquire token on behalf of + +In the case of web Apps or web APIs calling another downstream Web API in the name of the user, use the [On Behalf Of flow](/entra/identity-platform/v2-oauth2-on-behalf-of-flow) to acquire a token based on a user assertion (for example, SAML, JWT). The current app is a middle-tier service which was called with a token representing an end user. The current app can use such token (also known as a user assertion) to request another token to access downstream web API, on behalf of that user.The middle-tier app has no user interaction to obtain consent. For information on gaining consent upfront for your middle-tier app, see the [documentation](/entra/identity-platform/v2-oauth2-on-behalf-of-flow#gaining-consent-for-the-middle-tier-application). + +Here's an example of code that acquires an access token using the [`acquire_token_on_behalf_of`](/python/api/msal/msal.application.confidentialclientapplication#msal-application-confidentialclientapplication-acquire-token-on-behalf-of) method and the Flask framework. In this case, the downstream API is the Azure Management Subscriptions endpoint. + +```python +def get(self, request): # a web service endpoint receiving a request + + scopes = ["your-scopes"] + downstream_api = "https://your-downstreamapi.com/resource" #your downstream API resource endpoint + current_access_token = request.headers.get("Authorization", None) + + # initialize the app + app = msal.ConfidentialClientApplication(...) # refer to initialization of the app documentation + + #acquire token on behalf of the user that called this API + downstream_api_access_token = app.acquire_token_on_behalf_of( + user_assertion=current_app_access_token.split(' ')[1], + scopes=_scopes + ) + + if "access_token" in result: + access_token = result["access_token"] + # use access_token to call dowstream API e.g + requests.get(downstream_api, headers={'Authorization': f'Bearer {downstream_api_access_token}'}) + else: + print(result.get("error")) +``` + +## Acquire token by authorization code flow + +For Web apps authenticating in the name of a user, acquire tokens through [authorization code](/entra/identity-platform/v2-oauth2-auth-code-flow) after letting the user sign-in through the authorization request URL. This is typically the mechanism used by an application which lets the user sign-in using OpenID Connect but then wants to access Web APIs for this particular user. + +You'll first need to initiate auth code flow using the [`initiate_auth_code_flow`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-initiate-auth-code-flow). This method takes in among other parameters a redirect URI and state string. The value of the state parameter is also included in token response. If this value is absent, MSAL Python will automatically generate one internally. The redirect URI provided must match the redirect URI registered in the Microsoft Entra admin center. This method returns the auth code flow which is a dictionary containing auth_uri and a state. The auth_uri is the URL that the user needs to visit to sign in. + +```python +flow = app.initiate_auth_code_flow( + scopes=config["scope"], redirect_uri=config["redirect_uri"], state="your-state-value") + +if "error" in flow: + print(flow.get("error")) + +# Save the response somewhere e.g in session +session["auth_flow"] = flow + +# At this point, the app should guide the user to visit the auth ur (session["auth_flow"]["auth_uri"]) +``` + +The response from visiting the auth_uri endpoints is used in the [`acquire_token_by_auth_code_flow`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-auth-code-flow) method. The state is a unique identifier that you can use to verify the response from the authorization server. The user should consent to scopes during login. -:::zone-end +```python +# The uth_response value from visiting the auth_uri endpoint is passed as a query string +# You can change this by passing a value to the response_mode in the initiate_auth_code_flow method +try: + result = app.acquire_token_by_auth_code_flow(session.get("flow", {}), auth_response) + + if "access_token" in result: + access_token = result["access_token"] + else: + print(result.get("error")) +except ValueError: # Usually caused by CSRF + pass # Simply ignore them +``` ## MSAL Python token caching -Both public and confidential client applications support token caching, handled direclt by MSAL Python. Applications should try to get a token from the cache first before relying on any other means. Take a look at the [recommended token acquisition pattern](/azure/active-directory/develop/scenario-desktop-acquire-token?tabs=python) to learn more. +Both public and confidential client applications support token caching, handled direct by MSAL Python. Applications should try to get a token from the cache first before relying on any other means. Take a look at the [recommended token acquisition pattern](/azure/active-directory/develop/scenario-desktop-acquire-token?tabs=python) to learn more. To be able to persist the cache, the developers will need to configure the [token cache serialization](/azure/active-directory/develop/msal-python-token-cache-serialization) logic. From d996feb835ac9ac5f28722d60deed1bd88e95079 Mon Sep 17 00:00:00 2001 From: Sherman Ouko <12745944+SHERMANOUKO@users.noreply.github.com> Date: Wed, 6 Mar 2024 19:29:17 +0300 Subject: [PATCH 06/15] Update qcquire token documentation --- .../getting-started/acquiring-tokens.md | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/msal-python-conceptual/getting-started/acquiring-tokens.md b/msal-python-conceptual/getting-started/acquiring-tokens.md index f538fed..ad8f1ef 100644 --- a/msal-python-conceptual/getting-started/acquiring-tokens.md +++ b/msal-python-conceptual/getting-started/acquiring-tokens.md @@ -1,6 +1,6 @@ --- title: Acquire tokens for your app -description: Learn how to acquire tokens for your Python appliccation. You can acquire tokens silently or interactively through a web browser. +description: Learn how to acquire tokens for your Python application. You can acquire tokens silently or interactively through a web browser. author: SHERMANOUKO manager: CelesteDG ms.service: msal @@ -19,11 +19,11 @@ There are many ways of acquiring a token with MSAL Python. Some require user int ## Prerequisites -Before you acquire tokens with MSAL Python, make sure learn how to instantiate a [client application](./client-applications.md). +Before you acquire tokens with MSAL Python, learn about [types of client application](./client-applications.md). ## Get user account -An app can acquire a token as itself or on behalf of a user. To acquire a token on behalf of a user, the app needs to know the user's account. MSAL Python provides the [`get_accounts`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-get-accounts) method to get the user's account. This method is available on both [`PublicClientApplication`](/python/api/msal/msal.application.publicclientapplication) and [`ConfidentialClientApplication`](/python/api/msal/msal.application.confidentialclientapplication) classes. The method returns a list of accounts which you the user has previously signed in with, that is, exists in cache. +An app can acquire a token as itself or on behalf of a user. To acquire a token on behalf of a user, the app needs to know the user's account. MSAL Python provides the [`get_accounts`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-get-accounts) method to get the user's account. This method is available on both [`PublicClientApplication`](/python/api/msal/msal.application.publicclientapplication) and [`ConfidentialClientApplication`](/python/api/msal/msal.application.confidentialclientapplication) classes. The method returns a list of accounts that the user has previously signed in with, that is, exists in cache. ```python accounts = app.get_accounts(username=user.get("preferred_username")) @@ -36,17 +36,17 @@ The account selected by the user for sign-in can later be used in `acquire_token There are several authentication flows that can be used to acquire tokens with MSAL Python. You can find more information on these flows on the [Microsoft identity platform documentation](/entra/identity-platform/v2-oauth2-auth-code-flow). > [!WARNING] -> Always use MSAL to handle to get security tokens and call protected web APIs in your apps. We don't recommend you implementing your own token acquisition logic. These flows are to help you have a better understanding of how things work. If you are securing a web application, we recommend using the [identity](https://pypi.org/project/identity/) library. This library is not officially maintained by Microsoft but it implements most of the logic you need to acquire tokens in web apps. +> Always use MSAL to handle to get security tokens and call protected web APIs in your apps. We don't recommend you implementing your own token acquisition logic. These flows are to help you have a better understanding of how things work. If you are securing a web application, we recommend using the [identity](https://pypi.org/project/identity/) library. This library isn't officially maintained by Microsoft but it implements most of the logic you need to acquire tokens in web apps. ## Interactive vs silent MSAL Python supports both interactive and silent token acquisition. Interactive token acquisition requires user interaction, while silent token acquisition doesn't. Public clients generally require user interaction while confidential clients rely on pre-provisioned credentials, like certificates and secrets. -Use the [`acquire_token_silent_with_error`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent-with-error) method to silently acquire a token. This method finds a valid access token from cache, or a valid refresh token from cache and then automatically use it to redeem a new access token. If neither is true, you'll need to use an interactive method to acquire the token. +Use the [`acquire_token_silent_with_error`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent-with-error) method to silently acquire a token. This method finds a valid access token from cache, or a valid refresh token from cache and then automatically use it to redeem a new access token. If neither is true, you need to use an interactive method to acquire the token. If your app doesn't care about the exact token refresh error during token cache look-up, then the [`acquire_token_silent`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent) method is recommended. -An example usage of this method(s) is as shown in the following code snippet. +An example usage of this method is as shown in the following code snippet. ```python if accounts: @@ -68,17 +68,17 @@ if accounts: print(result.get("correlation_id")) # You may need this when reporting a bug ``` -Several methods are available for interactive token acquisition. The method to use depends on the type of app you are building and the token grant flow applicable to your scenario. +Several methods are available for interactive token acquisition. The method to use depends on the type of app you're building and the token grant flow applicable to your scenario. ## Public clients interactive token acquisition -Public client applications can't securely store a secret and can only authenticate the user that is interacting with the product. MSAL Python exposes most of the token acquisition logic for public applications through [`PublicClientApplication`](xref:msal.application.PublicClientApplication). Using this class enables developers to: +Public client applications can't securely store a secret and can only authenticate the user that is interacting with the product. MSAL Python exposes the token acquisition logic for public applications through [`PublicClientApplication`](xref:msal.application.PublicClientApplication). The following are the different methods available for public client applications to acquire tokens. ### Device code flow -For applications running on devices which don't have a web browser, it's possible to acquire a token through the [device code flow](/entra/identity-platform/v2-oauth2-device-code), which provides the user with a URL and a code. The user goes to a web browser on another device, enters the code and signs in. On successful authentication, Microsoft Entra will return a token to the browser-less device. +For applications running on devices that don't have a web browser, it's possible to acquire a token through the [device code flow](/entra/identity-platform/v2-oauth2-device-code). This flow provides the user with a URL and a code. The user goes to a web browser on another device, enters the code and signs in. On successful authentication, Microsoft Entra returns a token to the browser-less device. -First, you'll need to call the [`initiate_device_flow`](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-initiate-device-flow) method +First, you call the [`initiate_device_flow`](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-initiate-device-flow) method. ```python flow = app.initiate_device_flow(scopes=config["scope"]) @@ -93,7 +93,7 @@ sys.stdout.flush() # Some terminal needs this to ensure the message is shown # input("Press Enter after signing in from another device to proceed, CTRL+C to abort.") ``` -You then pass the flow dictionary object to the [`acquire_token_by_device_flow`](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-by-device-flow) method to get the token. By default, this method will block the current thread. You can follow [these instructions](https://msal-python.readthedocs.io/en/latest/#msal.PublicClientApplication.acquire_token_by_device_flow) to shorten the block time or you may even turn off the blocking behavior and then keep calling [`acquire_token_by_device_flow`](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-by-device-flow) in your own customized loop. +You then pass the flow dictionary object to the [`acquire_token_by_device_flow`](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-by-device-flow) method to get the token. By default, this method blocks the current thread. You can follow [these instructions](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-acquire-token-by-device-flow) to shorten the block time or you can even turn off the blocking behavior and then keep calling `acquire_token_by_device_flow` in your own customized loop. ```python result = app.acquire_token_by_device_flow(flow) @@ -108,7 +108,7 @@ A successful response a dictionary with an `access_token` key. ### Acquire token interactive -MSAL Python also offers the ability for public client apps (Desktops and Mobile) to acquire tokens as the user with the help of an interactive flow after letting the user sign-in through the authorization request URL via a web browser. You'll need to set the redirect URI of your app to `http://localhost` in the Microsoft Entra admin center for your app registration. If you opt in to use broker during `PublicClientApplication` creation, your app also needs `ms-appx-web://Microsoft.AAD.BrokerPlugin/YOUR_CLIENT_ID` as a redirect URI. +MSAL Python also offers the ability for public client apps (Desktops and Mobile) to acquire tokens as the user. The user signs in through the authorization request URL via a web browser. Set the redirect URI of your app to `http://localhost` in the Microsoft Entra admin center for your app registration. If you opt in to [use broker](../advanced/wam.md) during `PublicClientApplication` creation, your app also needs to register `ms-appx-web://Microsoft.AAD.BrokerPlugin/YOUR_CLIENT_ID` as a redirect URI. ```python result = app.acquire_token_interactive( # It automatically provides PKCE protection @@ -136,11 +136,11 @@ else: ## Confidential clients interactive token acquisition -Confidential client applications can securely store a secret and can authenticate both on behalf of an application as well as on behalf of a given user. With MSAL Python, developers can use [`ConfidentialClientApplication`](xref:msal.application.ConfidentialClientApplication) to access confidential client application capabilities, such as: +Confidential client applications can securely store a secret and can authenticate both on behalf of an application as well as on behalf of a given user. MSAL Python gives developers various methods to acquire tokens when developing [`ConfidentialClientApplication`](xref:msal.application.ConfidentialClientApplication). ### Acquire token for client -Acquire token as the application itself using [client credentials](/entra/identity-platform/v2-oauth2-client-creds-grant-flow), and not for a user. For example, this can be used in applications which process users in batches and not one particular user, such as syncing tools. MSAL Python provides the [`acquire_token_for_client`](/python/api/msal/msal.application.confidentialclientapplication#msal-application-confidentialclientapplication-acquire-token-for-client) method to do this. Since MSAL Python 1.23, this method will automatically look for token from cache, and only send request to Identity Provider when cache misses. +Acquire token as the application itself using [client credentials](/entra/identity-platform/v2-oauth2-client-creds-grant-flow), and not for a user. For example, this can be used in applications that process users in batches and not one particular user, such as syncing tools. MSAL Python provides the [`acquire_token_for_client`](/python/api/msal/msal.application.confidentialclientapplication#msal-application-confidentialclientapplication-acquire-token-for-client) method to do this. Since MSAL Python 1.23, this method automatically looks for token from cache, and only sends request to identity provider when cache misses. ```python result = app.acquire_token_for_client(scopes=config["scope"]) @@ -153,9 +153,9 @@ else: ### Acquire token on behalf of -In the case of web Apps or web APIs calling another downstream Web API in the name of the user, use the [On Behalf Of flow](/entra/identity-platform/v2-oauth2-on-behalf-of-flow) to acquire a token based on a user assertion (for example, SAML, JWT). The current app is a middle-tier service which was called with a token representing an end user. The current app can use such token (also known as a user assertion) to request another token to access downstream web API, on behalf of that user.The middle-tier app has no user interaction to obtain consent. For information on gaining consent upfront for your middle-tier app, see the [documentation](/entra/identity-platform/v2-oauth2-on-behalf-of-flow#gaining-consent-for-the-middle-tier-application). +In the case of web apps or web APIs calling another downstream Web API in the name of the user, use the [On Behalf Of flow](/entra/identity-platform/v2-oauth2-on-behalf-of-flow) to acquire a token based on a user assertion (for example, SAML, JWT). The current app is a middle-tier service that was called with a token representing an end user. The current app can use such token, also known as a user assertion, to request another token to access downstream web API on behalf of that user. The middle-tier app has no user interaction to obtain consent. For information on gaining consent upfront for your middle-tier app, see the [documentation](/entra/identity-platform/v2-oauth2-on-behalf-of-flow#gaining-consent-for-the-middle-tier-application). -Here's an example of code that acquires an access token using the [`acquire_token_on_behalf_of`](/python/api/msal/msal.application.confidentialclientapplication#msal-application-confidentialclientapplication-acquire-token-on-behalf-of) method and the Flask framework. In this case, the downstream API is the Azure Management Subscriptions endpoint. +Here's an example of code that acquires an access token using the [`acquire_token_on_behalf_of`](/python/api/msal/msal.application.confidentialclientapplication#msal-application-confidentialclientapplication-acquire-token-on-behalf-of) method. ```python def get(self, request): # a web service endpoint receiving a request @@ -183,9 +183,9 @@ def get(self, request): # a web service endpoint receiving a request ## Acquire token by authorization code flow -For Web apps authenticating in the name of a user, acquire tokens through [authorization code](/entra/identity-platform/v2-oauth2-auth-code-flow) after letting the user sign-in through the authorization request URL. This is typically the mechanism used by an application which lets the user sign-in using OpenID Connect but then wants to access Web APIs for this particular user. +For web apps authenticating in the name of a user, acquire tokens through [authorization code](/entra/identity-platform/v2-oauth2-auth-code-flow) after letting the user sign-in through the authorization request URL. This is typically the mechanism used by an application that lets the user sign-in and access Web APIs for this particular user. -You'll first need to initiate auth code flow using the [`initiate_auth_code_flow`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-initiate-auth-code-flow). This method takes in among other parameters a redirect URI and state string. The value of the state parameter is also included in token response. If this value is absent, MSAL Python will automatically generate one internally. The redirect URI provided must match the redirect URI registered in the Microsoft Entra admin center. This method returns the auth code flow which is a dictionary containing auth_uri and a state. The auth_uri is the URL that the user needs to visit to sign in. +You'll first need to initiate auth code flow using the [`initiate_auth_code_flow`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-initiate-auth-code-flow). This method takes in among other parameters a redirect URI and state string. The value of the state parameter is also included in token response. If this value is absent, MSAL Python will automatically generate one internally. The redirect URI provided must match the redirect URI registered in the Microsoft Entra admin center. This method returns the auth code flow that is a dictionary containing auth_uri and a state. The auth_uri is the URL that the user needs to visit to sign in. ```python flow = app.initiate_auth_code_flow( @@ -200,7 +200,7 @@ session["auth_flow"] = flow # At this point, the app should guide the user to visit the auth ur (session["auth_flow"]["auth_uri"]) ``` -The response from visiting the auth_uri endpoints is used in the [`acquire_token_by_auth_code_flow`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-auth-code-flow) method. The state is a unique identifier that you can use to verify the response from the authorization server. The user should consent to scopes during login. +The response from visiting the auth_uri endpoints is used in the [`acquire_token_by_auth_code_flow`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-by-auth-code-flow) method. The state is a unique identifier that you can use to verify the response from the authorization server. The user should consent to scopes during sign-in. ```python # The uth_response value from visiting the auth_uri endpoint is passed as a query string @@ -220,4 +220,4 @@ except ValueError: # Usually caused by CSRF Both public and confidential client applications support token caching, handled direct by MSAL Python. Applications should try to get a token from the cache first before relying on any other means. Take a look at the [recommended token acquisition pattern](/azure/active-directory/develop/scenario-desktop-acquire-token?tabs=python) to learn more. -To be able to persist the cache, the developers will need to configure the [token cache serialization](/azure/active-directory/develop/msal-python-token-cache-serialization) logic. +To be able to persist the cache, the developers need to configure the [token cache serialization](/azure/active-directory/develop/msal-python-token-cache-serialization) logic. From d392c5282a169ffae498eb10eabaf92ab48c5afb Mon Sep 17 00:00:00 2001 From: Sherman Ouko <12745944+SHERMANOUKO@users.noreply.github.com> Date: Thu, 7 Mar 2024 13:55:21 +0300 Subject: [PATCH 07/15] Improve client app documentation --- .../getting-started/client-applications.md | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/msal-python-conceptual/getting-started/client-applications.md b/msal-python-conceptual/getting-started/client-applications.md index f6062a5..b981788 100644 --- a/msal-python-conceptual/getting-started/client-applications.md +++ b/msal-python-conceptual/getting-started/client-applications.md @@ -1,52 +1,69 @@ --- title: Client applications description: "How to instantiate client applications in MSAL Python." -author: Dickson-Mwendia +author: SHERMANOUKO manager: CelesteDG ms.service: msal ms.subservice: msal-python ms.topic: conceptual -ms.date: 02/07/2024 -ms.author: dmwendia -ms.reviewer: shermanouko, rayluo +ms.date: 03/07/2024 +ms.author: shermanouko +ms.reviewer: dmwendia, rayluo --- # Client applications -## Instantiating an application +Microsoft Authentication Library (MSAL) Python supports two types of client applications: public client applications and confidential client applications. The client types are distinguished by their ability to authenticate securely with the authorization server and to hold sensitive, identity proving information so that it can't be accessed or known to a user within the scope of its access. This article focuses on how to initialize these applications using MSAL Python. -### Prerequisites +## Prerequisites -Before instantiating your app with MSAL Python: +This article doesn't go deep into defining what a public and confidential client applications are. Visit the identity platform docs to learn more about [public and confidential client applications](/entra/identity-platform/msal-client-applications). -1. Understand the types of client applications available - [Public Client and Confidential Client applications](/azure/active-directory/develop/msal-client-applications). -1. You'll need to [register the application](/azure/active-directory/develop/quickstart-register-app) with Microsoft Entra ID. From the registration page, you will need: - - The application client identifier (a string in the form of a GUID) - - The identity provider URL (the instance) and the sign-in audience for your application. These two parameters are collectively known as the **authority**. - - If necessary, the tenant identifier (also a GUID) in case you are writing a line of business application scoped to just your organization (also known as a single-tenant application). - - If you are building a confidential client app, you will need to create an application secret in the form of a string or certificate. - - For web applications, you'll have also set the redirect URL that Microsoft Entra ID will use to return the code. For desktop applications you will need to add `http://localhost` if you're not relying on authentication brokers. +## Instantiate an application -### Instantiating a public client application +You require an app registration to initiate an app. [Register an app](/entra/identity-platform/quickstart-register-app) in the Microsoft Entra admin center. From the registration page, you need: + +- The application client identifieR. This is a string in the form of a GUID. +- The identity provider URL (the instance) and the sign-in audience for your application. These two parameters are collectively known as the *authority*. +- If necessary, the tenant identifier (also a GUID) in case you're writing a line of business application scoped to just your organization (also known as a single-tenant application). +- If you're building a confidential client app, create an application secret in the form of a string or certificate. +- For web applications, set the redirect URL that Microsoft Entra ID uses to return the code. For desktop applications, add `http://localhost` if you're not relying on authentication brokers. + +## Instantiate a public client application Public client applications use the [`PublicClientApplication`](xref:msal.application.PublicClientApplication) class. ```python +import msal + app = msal.PublicClientApplication( "client_id", authority="authority", ) ``` -### Instantiating a confidential client application +## Instantiate a confidential client application Confidential client applications use the [`ConfidentialClientApplication`](xref:msal.application.ConfidentialClientApplication) class. ```python +import msal + app = msal.ConfidentialClientApplication( "client_id", authority="authority", client_credential="client_secret", ) ``` + +## Caching + +When you instantiate a client application, there are two parameters you can use to define your caching preferences. These parameters are: `token_cache` and `http_cache`. + +- `token_cache` sets the token cache used by the client application instance. By default, an in-memory cache is created and used. For more information, see [token caching in MSAL Python](msal-python-token-cache-serialization.md). +- `http_cache` is available in MSAL Python version 1.16+. This automatically caches some finite number of nontoken http responses, so that long-lived `PublicClientApplication` and `ConfidentialClientApplication` instances would be more performant and responsive in some situations. If the `http_cache` parameter isn't provided, MSAL uses an in-memory dict. If your app is a command-line app (CLI), you would want to persist your `http_cache` across different CLI runs. For more information, see the [reference guide](/python/api/msal/msal.application.clientapplication). + +## Next steps + +[Acquire tokens for your app](acquiring-tokens.md). From 4e941b58699c2c0494b83c7c46a3f80acca6d8fa Mon Sep 17 00:00:00 2001 From: Sherman Ouko <12745944+SHERMANOUKO@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:26:52 +0300 Subject: [PATCH 08/15] Improve client app documentation --- msal-python-conceptual/getting-started/client-applications.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/getting-started/client-applications.md b/msal-python-conceptual/getting-started/client-applications.md index b981788..9f4aa27 100644 --- a/msal-python-conceptual/getting-started/client-applications.md +++ b/msal-python-conceptual/getting-started/client-applications.md @@ -61,7 +61,7 @@ app = msal.ConfidentialClientApplication( When you instantiate a client application, there are two parameters you can use to define your caching preferences. These parameters are: `token_cache` and `http_cache`. -- `token_cache` sets the token cache used by the client application instance. By default, an in-memory cache is created and used. For more information, see [token caching in MSAL Python](msal-python-token-cache-serialization.md). +- `token_cache` sets the token cache used by the client application instance. By default, an in-memory cache is created and used. For more information, see [token caching in MSAL Python](../advanced/msal-python-token-cache-serialization.md). - `http_cache` is available in MSAL Python version 1.16+. This automatically caches some finite number of nontoken http responses, so that long-lived `PublicClientApplication` and `ConfidentialClientApplication` instances would be more performant and responsive in some situations. If the `http_cache` parameter isn't provided, MSAL uses an in-memory dict. If your app is a command-line app (CLI), you would want to persist your `http_cache` across different CLI runs. For more information, see the [reference guide](/python/api/msal/msal.application.clientapplication). ## Next steps From 69e947e624c9247909c5c20a439ee04f9327fbc0 Mon Sep 17 00:00:00 2001 From: Den Delimarsky <53200638+localden@users.noreply.github.com> Date: Fri, 15 Mar 2024 20:19:19 -0700 Subject: [PATCH 09/15] Update msal-python-conceptual/index.md Co-authored-by: Dickson Mwendia <64727760+Dickson-Mwendia@users.noreply.github.com> --- msal-python-conceptual/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/index.md b/msal-python-conceptual/index.md index 4ec699c..d794bd1 100644 --- a/msal-python-conceptual/index.md +++ b/msal-python-conceptual/index.md @@ -115,7 +115,7 @@ Acquiring tokens with MSAL Python follows a three-step pattern. There will be so TRhere are several samples you can use to get started with MSAL Python. -- Samples from the [library repository](https://github.com/AzureAD/microsoft-authentication-library-for-python/blob/1.22.0/sample/interactive_sample.py). +- Samples from the [library repository](https://github.com/AzureAD/microsoft-authentication-library-for-python/blob/1.22.0/sample). These samples demonstrate the different configurations and auth flows that you implement using MSAL Python. - A single repository with [samples used in our documentation](https://github.com/Azure-Samples/ms-identity-docs-code-python). These samples have supporting documentation to help you build and replicate them from scratch. ## References From 094b1bee7eafcdd2a2646a69b40a9ea7efb52135 Mon Sep 17 00:00:00 2001 From: Den Delimarsky <53200638+localden@users.noreply.github.com> Date: Fri, 15 Mar 2024 20:19:25 -0700 Subject: [PATCH 10/15] Update msal-python-conceptual/index.md Co-authored-by: Dickson Mwendia <64727760+Dickson-Mwendia@users.noreply.github.com> --- msal-python-conceptual/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/index.md b/msal-python-conceptual/index.md index d794bd1..25e8086 100644 --- a/msal-python-conceptual/index.md +++ b/msal-python-conceptual/index.md @@ -113,7 +113,7 @@ Acquiring tokens with MSAL Python follows a three-step pattern. There will be so ## Samples -TRhere are several samples you can use to get started with MSAL Python. +There are several samples you can use to get started with MSAL Python. - Samples from the [library repository](https://github.com/AzureAD/microsoft-authentication-library-for-python/blob/1.22.0/sample). These samples demonstrate the different configurations and auth flows that you implement using MSAL Python. - A single repository with [samples used in our documentation](https://github.com/Azure-Samples/ms-identity-docs-code-python). These samples have supporting documentation to help you build and replicate them from scratch. From 86fd4c90f9ef3f8b8ec029c7a33f1193528121a3 Mon Sep 17 00:00:00 2001 From: Den Delimarsky <53200638+localden@users.noreply.github.com> Date: Fri, 15 Mar 2024 20:19:30 -0700 Subject: [PATCH 11/15] Update msal-python-conceptual/index.md Co-authored-by: Dickson Mwendia <64727760+Dickson-Mwendia@users.noreply.github.com> --- msal-python-conceptual/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/index.md b/msal-python-conceptual/index.md index 25e8086..68b3f89 100644 --- a/msal-python-conceptual/index.md +++ b/msal-python-conceptual/index.md @@ -14,7 +14,7 @@ ms.reviewer: dmwendia, rayluo # Microsoft Authentication Library (MSAL) for Python -The Microsoft Authentication Library (MSAL) for Python library enables you to sign in users or apps with Microsoft identities. These identities include work and school accounts, personal microsoft accounts, social accounts, customer accounts and so on. Using MSAL Python, you can acquire tokens from Microsoft Entra to call protected web APIs such as [Microsoft Graph](https://graph.microsoft.io/), other Microsoft APIs, or your own APIs. MSAL Python supports a variety of application types, including public client applications (desktop and mobile) and confidential client applications (web apps, web APIs, and daemon applications). +The Microsoft Authentication Library (MSAL) for Python library enables you to sign in users or apps with Microsoft identities. These identities include work and school accounts, personal Microsoft accounts, social accounts, customer accounts, and so on. Using MSAL Python, you can acquire tokens from Microsoft Entra to call protected web APIs such as [Microsoft Graph](https://graph.microsoft.io/), other Microsoft APIs, or your own APIs. MSAL Python supports various application types, including public client applications (desktop and mobile) and confidential client applications (web apps, web APIs, and daemon applications). ## Prerequisites From 5ff0303447ed8fdc9d17311232c28168a893a480 Mon Sep 17 00:00:00 2001 From: Den Delimarsky <53200638+localden@users.noreply.github.com> Date: Fri, 15 Mar 2024 20:19:35 -0700 Subject: [PATCH 12/15] Update msal-python-conceptual/index.md Co-authored-by: Dickson Mwendia <64727760+Dickson-Mwendia@users.noreply.github.com> --- msal-python-conceptual/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/index.md b/msal-python-conceptual/index.md index 68b3f89..0c549b5 100644 --- a/msal-python-conceptual/index.md +++ b/msal-python-conceptual/index.md @@ -90,7 +90,7 @@ Acquiring tokens with MSAL Python follows a three-step pattern. There will be so result = app.acquire_token_silent(["User.Read"], account=chosen) ``` -1. If there is no suitable token in the cache or you've chosen to skip the previous step, send a request to Microsoft Entra ID to get a token. There are different methods based on your client type and scenario, but for the purposes of the example we're showing how to use [`acquire_token_interactive`](xref:msal.application.PublicClientApplication.acquire_token_interactive) which will prompt the user to provide their credentials. +1. If there's no suitable token in the cache or you chose to skip the previous step, send a request to Microsoft Entra ID to get a token. There are different methods based on your client type and scenario, but for the purposes of the example we're showing how to use [`acquire_token_interactive`](xref:msal.application.PublicClientApplication.acquire_token_interactive), which prompts the user to provide their credentials. ```python if not result: From 9d803b1591823d68db739fde71a8f7a33d1a46ee Mon Sep 17 00:00:00 2001 From: Den Delimarsky <53200638+localden@users.noreply.github.com> Date: Fri, 15 Mar 2024 20:19:40 -0700 Subject: [PATCH 13/15] Update msal-python-conceptual/index.md Co-authored-by: Dickson Mwendia <64727760+Dickson-Mwendia@users.noreply.github.com> --- msal-python-conceptual/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/index.md b/msal-python-conceptual/index.md index 0c549b5..6c004ea 100644 --- a/msal-python-conceptual/index.md +++ b/msal-python-conceptual/index.md @@ -43,7 +43,7 @@ MSAL Python is part of the [Microsoft identity platform](/entra/identity-platfor To use MSAL Python, register an application with the Microsoft identity platform. You'll need an Azure account with an active subscription. [Create a free account](https://signup.azure.com/) if you don't have one. You can register your app in a [customer tenant](/entra/external-id/customers/quickstart-tenant-setup) or [workforce tenant](/entra/identity-platform/scenario-web-app-sign-user-app-registration?tabs=python). -MSAL Python can be used by applications to acquire tokens to access protected APIs. Tokens can be acquired by different application types. These app types include desktop applications, web applications, web APIs, and applications running on devices that don't have a browser (such as IoT devices). Different app types follow different auth flows. +Applications can use MSAL Python to acquire tokens for accessing protected APIs. Different app types acquire tokens using different auth flows. The supported app types include desktop applications, web applications, web APIs, and applications running on devices that don't have a browser (such as IoT devices). In MSAL Python, applications are categorized as follows: From 56f1a878e178d40fc357fa65de23676cc9061f04 Mon Sep 17 00:00:00 2001 From: Den Delimarsky <53200638+localden@users.noreply.github.com> Date: Fri, 15 Mar 2024 21:04:01 -0700 Subject: [PATCH 14/15] Update index.md --- msal-python-conceptual/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msal-python-conceptual/index.md b/msal-python-conceptual/index.md index 6c004ea..d26d76c 100644 --- a/msal-python-conceptual/index.md +++ b/msal-python-conceptual/index.md @@ -31,7 +31,7 @@ pip install msal ## Identity concepts -MSAL Python is part of the [Microsoft identity platform](/entra/identity-platform/v2-overview) ecosystem. It's important to farmiliarize yourself with the following concepts to effectively use MSAL Python to protect your applications and APIs: +MSAL Python is part of the [Microsoft identity platform](/entra/identity-platform/v2-overview) ecosystem. It's important to familiarize yourself with the following concepts to effectively use MSAL Python to protect your applications and APIs: - [Identity and access management](/entra/fundamentals/identity-fundamental-concepts) - [Authentication and authorization](/entra/identity-platform/authentication-vs-authorization) From bbf8ba8d7e64f008ea6a3dd6c4175fc9f810cbcd Mon Sep 17 00:00:00 2001 From: Sherman Ouko <12745944+SHERMANOUKO@users.noreply.github.com> Date: Mon, 18 Mar 2024 09:36:16 +0300 Subject: [PATCH 15/15] Minor updates --- .../getting-started/acquiring-tokens.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msal-python-conceptual/getting-started/acquiring-tokens.md b/msal-python-conceptual/getting-started/acquiring-tokens.md index ad8f1ef..812cb84 100644 --- a/msal-python-conceptual/getting-started/acquiring-tokens.md +++ b/msal-python-conceptual/getting-started/acquiring-tokens.md @@ -36,13 +36,13 @@ The account selected by the user for sign-in can later be used in `acquire_token There are several authentication flows that can be used to acquire tokens with MSAL Python. You can find more information on these flows on the [Microsoft identity platform documentation](/entra/identity-platform/v2-oauth2-auth-code-flow). > [!WARNING] -> Always use MSAL to handle to get security tokens and call protected web APIs in your apps. We don't recommend you implementing your own token acquisition logic. These flows are to help you have a better understanding of how things work. If you are securing a web application, we recommend using the [identity](https://pypi.org/project/identity/) library. This library isn't officially maintained by Microsoft but it implements most of the logic you need to acquire tokens in web apps. +> Always use MSAL to get security tokens and call protected web APIs in your apps. We don't recommend you implementing your own token acquisition logic. These flows are to help you have a better understanding of how things work. If you're securing a web application, we recommend using the [identity](https://pypi.org/project/identity/) library. This library isn't officially maintained by Microsoft but it implements most of the logic you need to acquire tokens in web apps. ## Interactive vs silent MSAL Python supports both interactive and silent token acquisition. Interactive token acquisition requires user interaction, while silent token acquisition doesn't. Public clients generally require user interaction while confidential clients rely on pre-provisioned credentials, like certificates and secrets. -Use the [`acquire_token_silent_with_error`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent-with-error) method to silently acquire a token. This method finds a valid access token from cache, or a valid refresh token from cache and then automatically use it to redeem a new access token. If neither is true, you need to use an interactive method to acquire the token. +Use the [`acquire_token_silent_with_error`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent-with-error) method to silently acquire a token. This method finds a valid access token from cache, or a valid refresh token from cache and then automatically uses it to redeem a new access token. If neither is true, you need to use an interactive method to acquire the token. If your app doesn't care about the exact token refresh error during token cache look-up, then the [`acquire_token_silent`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-acquire-token-silent) method is recommended. @@ -76,7 +76,7 @@ Public client applications can't securely store a secret and can only authentica ### Device code flow -For applications running on devices that don't have a web browser, it's possible to acquire a token through the [device code flow](/entra/identity-platform/v2-oauth2-device-code). This flow provides the user with a URL and a code. The user goes to a web browser on another device, enters the code and signs in. On successful authentication, Microsoft Entra returns a token to the browser-less device. +[Device code flow](/entra/identity-platform/v2-oauth2-device-code) is used to acquire tokens in applications that run on devices that don't have access to a web browser. These are applications are known as headless applications. This flow provides the user with a URL and a code. The user goes to a web browser on another device, enters the code and signs in. On successful authentication, Microsoft Entra returns a token to the browser-less device. First, you call the [`initiate_device_flow`](/python/api/msal/msal.application.publicclientapplication#msal-application-publicclientapplication-initiate-device-flow) method. @@ -183,7 +183,7 @@ def get(self, request): # a web service endpoint receiving a request ## Acquire token by authorization code flow -For web apps authenticating in the name of a user, acquire tokens through [authorization code](/entra/identity-platform/v2-oauth2-auth-code-flow) after letting the user sign-in through the authorization request URL. This is typically the mechanism used by an application that lets the user sign-in and access Web APIs for this particular user. +For web apps authenticating in the name of a user, acquire tokens through [authorization code](/entra/identity-platform/v2-oauth2-auth-code-flow) after letting the user sign-in through the authorization request URL. This is typically the mechanism used by an application that lets the user sign-in and access web APIs for this particular user. You'll first need to initiate auth code flow using the [`initiate_auth_code_flow`](/python/api/msal/msal.application.clientapplication#msal-application-clientapplication-initiate-auth-code-flow). This method takes in among other parameters a redirect URI and state string. The value of the state parameter is also included in token response. If this value is absent, MSAL Python will automatically generate one internally. The redirect URI provided must match the redirect URI registered in the Microsoft Entra admin center. This method returns the auth code flow that is a dictionary containing auth_uri and a state. The auth_uri is the URL that the user needs to visit to sign in.