Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions msal-python-conceptual/TOC.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
- name: Getting started
href: index.md
items:
- name: Why use MSAL Python
href: getting-started/why-use-msal-python.md
- name: Register your app with Azure AD
href: /azure/active-directory/develop/active-directory-integrating-applications
- name: Client applications
href: getting-started/client-applications.md
- name: Acquiring tokens
href: getting-started/acquiring-tokens.md
- name: Calling a protected API
href: getting-started/call-protected-web-api.md

- name: Advanced topics
items:
- name: Using MSAL Python with Web Account Manager
href: advanced/wam.md
- name: Migrate to MSAL Python
href: /azure/active-directory/develop/migrate-python-adal-msal
- name: Logging
Expand Down
97 changes: 97 additions & 0 deletions msal-python-conceptual/advanced/wam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
title: Using MSAL Python with Web Account Manager
description: "If you are building a Windows application, you might consider simplifying how users authenticate with the help of an authentication broker - the Web Account Manager."
---

# Using MSAL Python with Web Account Manager

If you are building a Windows application, you might consider simplifying how users authenticate with the help of an _authentication broker_ - the [Web Account Manager](/windows/uwp/security/web-account-manager) (WAM).

>[!NOTE]
>WAM is only available on Windows 10 and above, as well as Windows Server 2019 and above.

To learn more about the benefits of using an authentication broker, refer to [What is a broker](/entra/msal/dotnet/acquiring-tokens/desktop-mobile/wam#what-is-a-broker) in the MSAL.NET documentation.

## Usage

To use the broker, you will need to install the broker-related packages in addition to the core MSAL from PyPI:

```bash
pip install msal[broker]>=1.20,<2
```

>[!IMPORTANT]
>If broker-related packages are not installed and you will try to use the authentication broker, you will get an error: `ImportError: You need to install dependency by: pip install "msal[broker]>=1.20,<2"`.

Next, you will need to instantiate a new [`PublicClientApplication`](xref:msal.application.PublicClientApplication) and set `allow_broker` to `True`. This will ensure that MSAL will try and communicate with WAM instead of popping up a new browser window.

```python
from msal import PublicClientApplication

app = PublicClientApplication(
"CLIENT_ID",
authority="https://login.microsoftonline.com/common",
allow_broker=True)
```

You can now acquire a token by calling [`acquire_token_interactive`](xref:msal.application.PublicClientApplication.acquire_token_interactive) and specifying a parent window handle through `parent_window_handle`:

```python
result = app.acquire_token_interactive(["User.ReadBasic.All"],
parent_window_handle=app.CONSOLE_WINDOW_HANDLE)
```

A parent window handle is required by WAM to ensure that the dialog is shown correctly on top of the requesting window. MSAL does not infer this directly due to the fact that there are many variables that might influence what window WAM needs to bind to, and developers building applications are best suited to decide what window that should be.

For console applications, MSAL makes it easy by offering an out-of-the-box solution to getting the window handle for the terminal - [`CONSOLE_WINDOW_HANDLE`](xref:msal.application.PublicClientApplication.CONSOLE_WINDOW_HANDLE). For desktop applications, additional work with the Windows API might be required to [get the window handle](/windows/apps/develop/ui-input/retrieve-hwnd). Helper packages, like [pywin32](https://pypi.org/project/pywin32/) can help with API calls.

Before executing your application, make sure that you configure the redirect URL for the desktop app:

>[!IMPORTANT]
>To use the Windows broker, your application needs to have the correct redirect URL configured in the Azure Portal, in the shape of:
>
>```bash
>ms-appx-web://microsoft.aad.brokerplugin/YOUR_CLIENT_ID
>```
>
>If the redirect URL is not configured, you will get a `broker_error` similar to `(pii). Status: Response_Status.Status_ApiContractViolation, Error code: 3399614473, Tag: 557973642`.

If configuration and instantiation was correct, once you run the application you should see the authentication broker kick in and allow the user to select the account they want to authenticate with.

![Example of WAM being called from Python](../media/wam-python.gif)

Worth noting that if you switch to using broker-based authentication, if the user was previously logged in and the signed-in state is still valid, calling [`acquire_token_interactive`](xref:msal.application.PublicClientApplication.acquire_token_interactive) will still result in a silent attempt to acquire a token, and only prompt when necessary. If you prefer to always prompt, you can use this optional parameter `prompt="select_account"`.

## Broker experience differences

Depending on the authority specified when instantiating [`PublicClientApplication`](xref:msal.application.PublicClientApplication), the broker user interface may be different.

### `/consumers`

Used for authenticating **only** with personal Microsoft accounts.

![WAM UI for consumers](../media/wam-consumers.png)

### `/common`

Used for authenticating with personal Microsoft accounts as well as work and school accounts.

![WAM UI for personal and work accounts](../media/wam-common.png)

### `/organizations`

Used for authenticating **only** with work and school accounts.

![WAM UI for work accounts only](../media/wam-organizations.png)

>[!NOTE]
>If `login_hint` is provided but the account is not yet registered in WAM, the hint will be automatically filled in the "Email or phone" field.

### `/TENANT_ID`

Used for authenticating **only** with work and school accounts within the specified tenant.

![WAM UI for tenant-specific accounts](../media/wam-tenant-specific.png)

>[!NOTE]
>If `login_hint` is provided but the account is not yet registered in WAM, the hint will be automatically filled in the "Email or phone" field.
3 changes: 2 additions & 1 deletion msal-python-conceptual/docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
{
"files": [
"**/*.png",
"**/*.jpg"
"**/*.jpg",
"**/*.gif"
],
"exclude": [
"**/obj/**",
Expand Down
2 changes: 1 addition & 1 deletion msal-python-conceptual/getting-started/acquiring-tokens.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Before acquiring tokens with MSAL Python, make sure to instantiate a [client app

## Token acquisition methods

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.
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.

### Public client applications

Expand Down
22 changes: 0 additions & 22 deletions msal-python-conceptual/getting-started/call-protected-web-api.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Before instantiating your app with MSAL Python:
- 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 Azure AD will use to return the code.
- For web applications, you'll have also set the redirect URL that Azure AD will use to return the code. For desktop applications you will need to add `http://localhost` if you're not relying on authentication brokers.

### Instantiating a public client application

Expand Down
37 changes: 0 additions & 37 deletions msal-python-conceptual/getting-started/why-use-msal-python.md

This file was deleted.

61 changes: 44 additions & 17 deletions msal-python-conceptual/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,39 @@ pip install msal

## Setting up

Before using MSAL Python, make sure to [register your application](/azure/active-directory/develop/quickstart-v2-register-an-app) with the Microsoft identity platform.
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**.

## Usage
>[!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.

## 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:

```python
from msal import PublicClientApplication
app = PublicClientApplication(
"your_client_id",
authority="https://login.microsoftonline.com/Enter_the_Tenant_Name_Here")
```
```python
from msal import PublicClientApplication

Later, each time you would want an access token, you start by declaring a variable that will hold the token result:
app = PublicClientApplication(
"your_client_id",
authority="https://login.microsoftonline.com/common")
```

```python
result = None # It is just an initial value. Please follow instructions below.
```
>[!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.

Instantiate a variable to hold the authentication result:

```python
result = None # It is just an initial value. Please follow instructions below.
```

2. 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.
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
Expand All @@ -57,15 +68,15 @@ Acquiring tokens with MSAL Python follows a three-step pattern. There will be so
# 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(["your_scope"], account=chosen)
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 Azure AD to get a token. There are different methods based on your client type and scenario. A sample flow can look like this:
3. If there is no suitable token in the cache or you've chosen to skip the previous step, send a request to Azure AD 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:
# So no suitable token exists in cache. Let's get a new one from Azure AD.
result = app.acquire_token_by_one_of_the_actual_method(..., scopes=["User.Read"])
result = app.acquire_token_interactive(scopes=["User.Read"])
if "access_token" in result:
print(result["access_token"]) # Yay!
else:
Expand All @@ -74,6 +85,18 @@ 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:
Expand All @@ -95,4 +118,8 @@ Key scenarios supported by MSAL Python:
- [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)

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.
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.

## Releases

Refer to [MSAL Python releases on GitHub](https://github.com/AzureAD/microsoft-authentication-library-for-python/releases).
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added msal-python-conceptual/media/redirect-urls.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added msal-python-conceptual/media/wam-common.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added msal-python-conceptual/media/wam-consumers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added msal-python-conceptual/media/wam-python.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion python/docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
{
"files": [
"**/*.png",
"**/*.jpg"
"**/*.jpg",
"**/*.gif"
],
"exclude": [
"**/obj/**",
Expand Down