Configure authentication in a sample Python web app by using Azure AD B2C

This article uses a sample Python web application to illustrate how to add Azure Active Directory B2C (Azure AD B2C) authentication to your web applications.

Overview

OpenID Connect (OIDC) is an authentication protocol that's built on OAuth 2.0. You can use OIDC to securely sign users in to an application. This web app sample uses the Microsoft Authentication Library (MSAL) for Python. The MSAL for Python simplifies adding authentication and authorization support to Python web apps.

The sign-in flow involves the following steps:

  1. Users go to the web app and select Sign-in.
  2. The app initiates an authentication request and redirects users to Azure AD B2C.
  3. Users sign up or sign in, reset the password, or sign in with a social account.
  4. After users sign in successfully, Azure AD B2C returns an ID token to the app.
  5. The app exchanges the authorization code with an ID token, validates the ID token, reads the claims, and then returns a secure page to users.

Sign-out

The sign-out flow involves the following steps:

  1. From the app, users sign out.
  2. The app clears its session objects, and the authentication library clears its token cache.
  3. The app takes users to the Azure AD B2C sign-out endpoint to terminate the Azure AD B2C session.
  4. Users are redirected back to the app.

Prerequisites

A computer that's running:

Step 1: Configure your user flow

When users try to sign in to your app, the app starts an authentication request to the authorization endpoint via a user flow. The user flow defines and controls the user experience. After users complete the user flow, Azure AD B2C generates a token and then redirects users back to your application.

If you haven't done so already, create a user flow or a custom policy.

Step 2: Register a web application

To enable your application to sign in with Azure AD B2C, register your app in the Azure AD B2C directory. Registering your app establishes a trust relationship between the app and Azure AD B2C.

During app registration, you'll specify the Redirect URI. The redirect URI is the endpoint to which users are redirected by Azure AD B2C after they authenticate with Azure AD B2C. The app registration process generates an Application ID, also known as the client ID, that uniquely identifies your app. After your app is registered, Azure AD B2C uses both the application ID and the redirect URI to create authentication requests.

Step 2.1: Register the app

To create the web app registration, do the following:

  1. Sign in to the Azure portal.

  2. Make sure you're using the directory that contains your Azure AD B2C tenant. Select the Directories + subscriptions icon in the portal toolbar.

  3. On the Portal settings | Directories + subscriptions page, find your Azure AD B2C directory in the Directory name list, and then select Switch.

  4. In the Azure portal, search for and select Azure AD B2C.

  5. Select App registrations, and then select New registration.

  6. Under Name, enter a name for the application (for example, webapp1).

  7. Under Supported account types, select Accounts in any identity provider or organizational directory (for authenticating users with user flows).

  8. Under Redirect URI, select Web and then, in the URL box, enter http://localhost:5000/getAToken.

  9. Under Permissions, select the Grant admin consent to openid and offline access permissions checkbox.

  10. Select Register.

  11. Select Overview.

  12. Record the Application (client) ID for later use, when you configure the web application.

    Screenshot of the web app Overview page for recording your web app ID.

Step 2.2: Create a web app client secret

Create a client secret for the registered web application. The web application uses the client secret to prove its identity when it requests tokens.

  1. Under Manage, select Certificates & secrets.
  2. Select New client secret.
  3. In the Description box, enter a description for the client secret (for example, clientsecret1).
  4. Under Expires, select a duration for which the secret is valid, and then select Add.
  5. Record the secret's Value. You'll use this value for configuration in a later step.

Step 3: Get the web app sample

Download the zip file, or clone the sample web application from GitHub.

git clone https://github.com/Azure-Samples/ms-identity-python-webapp.git

Extract the sample file to a folder where the total length of the path is 260 or fewer characters.

Step 4: Configure the sample web app

In the project's root directory, do the following:

  1. Rename the app_config.py file to app_config.py.OLD.
  2. Rename the app_config_b2c.py file to app_config.py.

Open the app_config.py file. This file contains information about your Azure AD B2C identity provider. Update the following app settings properties:

Key Value
b2c_tenant The first part of your Azure AD B2C tenant name (for example, contoso).
CLIENT_ID The web API application ID from step 2.1.
CLIENT_SECRET The client secret you created in step 2.2. To help increase security, consider storing it instead in an environment variable, as recommended in the comments.
*_user_flow The user flows or custom policy you created in step 1.

Your final configuration file should look like the following Python code:

import os

b2c_tenant = "contoso"
signupsignin_user_flow = "B2C_1_signupsignin"
editprofile_user_flow = "B2C_1_profileediting"
resetpassword_user_flow = "B2C_1_passwordreset"
authority_template = "https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{user_flow}"

CLIENT_ID = "11111111-1111-1111-1111-111111111111" # Application (client) ID of app registration

CLIENT_SECRET = "xxxxxxxxxxxxxxxxxxxxxxxx" # Placeholder - for use ONLY during testing.

Important

As noted in the code snippet comments, we recommend that you do not store secrets in plaintext in your application code. The hard-coded variable is used in the code sample for convenience only. Consider using an environment variable or a secret store, such as an Azure key vault.

Step 5: Run the sample web app

  1. In your console or terminal, switch to the directory that contains the sample. For example:

    cd ms-identity-python-webapp
    
  2. Install the required packages from PyPi and run the web app on your local machine by running the following commands:

    pip install -r requirements.txt
    flask run --host localhost --port 5000
    

    The console window displays the port number of the locally running application:

     * Serving Flask app "app" (lazy loading)
     * Environment: production
       WARNING: This is a development server. Do not use it in a production deployment.
       Use a production WSGI server instead.
     * Debug mode: off
     * Running on `http://localhost:5000/` (Press CTRL+C to quit)
    
  3. To view the web application running on your local machine, go to http://localhost:5000.

  4. Select Sign In.

    Screenshot showing the sign-in with Azure AD B2C.

  5. Complete the sign-up or sign-in process.

  6. After successful authentication, you'll see your display name, as shown here:

    Screenshot showing the web app token's display name claim.

Step 6: Call to a web API

To enable your app to sign in with Azure AD B2C and call a web API, you must register two applications in the Azure AD B2C directory.

  • The web application (Python) registration you already created in Step 2. This app registration enables your app to sign in with Azure AD B2C. The app registration process generates an Application ID, also known as the client ID, that uniquely identifies your app. For example, App ID: 1.

  • The web API registration enables your app to call a protected web API. The registration exposes the web API permissions (scopes). The app registration process generates an Application ID that uniquely identifies your web API (for example, App ID: 2). Grant your app (App ID: 1) permissions to the web API scopes (App ID: 2).

The app registrations and the application architecture are described in the following diagrams:

Diagram describing a web app with web API, registrations, and tokens.

After the authentication is completed, users interact with the app, which invokes a protected web API. The web API uses bearer token authentication. The bearer token is the access token that the app obtained from Azure AD B2C. The app passes the token in the authorization header of the HTTPS request.

Authorization: Bearer <token>

If the access token's scope doesn't match the web API's scopes, the authentication library obtains a new access token with the correct scopes.

Step 6.1: Register the web API app

To create the web API app registration (App ID: 2), follow these steps:

  1. Sign in to the Azure portal.

  2. Make sure you're using the directory that contains your Azure AD B2C tenant. Select the Directories + subscriptions icon in the portal toolbar.

  3. On the Portal settings | Directories + subscriptions page, find your Azure AD B2C directory in the Directory name list, and then select Switch.

  4. In the Azure portal, search for and select Azure AD B2C.

  5. Select App registrations, and then select New registration.

  6. For Name, enter a name for the application (for example, my-api1). Leave the default values for Redirect URI.

  7. Select Register.

  8. After the app registration is completed, select Overview.

  9. Record the Application (client) ID value for later use when you configure the web application.

    Screenshot that demonstrates how to get a web A P I application I D.

Step 6.2: Configure scopes

  1. Select the my-api1 application that you created (App ID: 2) to open its Overview page.

  2. Under Manage, select Expose an API.

  3. Next to Application ID URI, select the Set link. Replace the default value (GUID) with a unique name (for example, tasks-api), and then select Save.

    When your web application requests an access token for the web API, it should add this URI as the prefix for each scope that you define for the API.

  4. Under Scopes defined by this API, select Add a scope.

  5. To create a scope that defines read access to the API:

    1. For Scope name, enter tasks.read.
    2. For Admin consent display name, enter Read access to tasks API.
    3. For Admin consent description, enter Allows read access to the tasks API.
  6. Select Add scope.

  7. Select Add a scope, and then add a scope that defines write access to the API:

    1. For Scope name, enter tasks.write.
    2. For Admin consent display name, enter Write access to tasks API.
    3. For Admin consent description, enter Allows write access to the tasks API.
  8. Select Add scope.

Step 6.3: Grant the web app permissions

To grant your app (App ID: 1) permissions, follow these steps:

  1. Select App registrations, and then select the app that you created (App ID: 1).

  2. Under Manage, select API permissions.

  3. Under Configured permissions, select Add a permission.

  4. Select the My APIs tab.

  5. Select the API (App ID: 2) to which the web application should be granted access. For example, enter my-api1.

  6. Under Permission, expand tasks, and then select the scopes that you defined earlier (for example, tasks.read and tasks.write).

  7. Select Add permissions.

  8. Select Grant admin consent for <your tenant name>.

  9. Select Yes.

  10. Select Refresh, and then verify that Granted for ... appears under Status for both scopes.

  11. From the Configured permissions list, select your scope, and then copy the scope full name.

    Screenshot of the configured permissions pane, showing that read access permissions are granted.

Step 6.4: Configure your web API

This sample acquires an access token with the relevant scopes, which the web app can use for a web API. To call a web API from the code, use an existing web API or create a new one. For more information, see Enable authentication in your own web API by using Azure AD B2C.

Step 6.5: Configure the sample app with the web API

Open the app_config.py file. This file contains information about your Azure AD B2C identity provider. Update the following properties of the app settings:

Key Value
ENDPOINT The URI of your web API (for example, https://localhost:44332/hello).
SCOPE The web API scopes that you created.

Your final configuration file should look like the following Python code:

import os

b2c_tenant = "contoso"
signupsignin_user_flow = "B2C_1_signupsignin"
editprofile_user_flow = "B2C_1_profileediting"
resetpassword_user_flow = "B2C_1_passwordreset"
authority_template = "https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{user_flow}"

CLIENT_ID = "11111111-1111-1111-1111-111111111111" # Application (client) ID of app registration

CLIENT_SECRET = "xxxxxxxxxxxxxxxxxxxxxxxx" # Placeholder - for use ONLY during testing.

### More code here

# This is the API resource endpoint
ENDPOINT = 'https://localhost:44332' 


SCOPE = ["https://contoso.onmicrosoft.com/api/demo.read", "https://contoso.onmicrosoft.com/api/demo.write"] 

Step 6.6: Run the sample app

  1. In your console or terminal, switch to the directory that contains the sample.

  2. Stop the app. and then rerun it.

  3. Select Call Microsoft Graph API.

    Screenshot showing how to call a web API.

Step 7: Deploy your application

In a production application, the app registration redirect URI is ordinarily a publicly accessible endpoint where your app is running, such as https://contoso.com/getAToken.

You can add and modify redirect URIs in your registered applications at any time. The following restrictions apply to redirect URIs:

  • The reply URL must begin with the scheme https.
  • The reply URL is case-sensitive. Its case must match the case of the URL path of your running application.

Next steps