Introduction
The Microsoft identity platform is key to secure access to your web app. Users can authenticate to your app using their Azure AD identity or social accounts. The authorization model can be used to grant permissions to your backend app or standard APIs like Microsoft Graph. In this blog, a web application is discussed that does the following:
-
- Azure AD login with user role: basic or user role: premium
-
- Access to MS Graph using delegated permissions of signed-in user
-
- Access to backend using application permissions and app role
The code of the project can be found here, architecture can be found below.

The focus is to provide a working example using Microsoft Identity platform and to "get your hands dirty". The focus is less on explaining the internal workings of OAuth 2.0 and Azure AD. In the remaining of this blog, the following is discussed.
- Step 0: Preliminaries – set up frontend and backend
- Step 1: Access to frontend – Azure AD login, add user role
- Step 2: Access to Graph – Delegated permissons retrieving users details
- Step 3: Access to backend – Applications permissions retrieving data
- Miscellaneous: Other possibilities to configure project
- Conclusion
To learn how to access Azure SQL database using delegated or application permissions, see my previous blog. Notice that both blogs share the same git repo, so this project can be configured to access Azure SQL rather than a backend app.
Step 0. Preliminaries – setup frontend and backend
This sample shows how to build a Python frontend web app using Flask and MSAL Python and backend app using an Azure Function. In this step, the following sub steps are executed:
- 0.1: Create frontend web app
- 0.2: Create and configure frontend app registration
- 0.3. Create backend Azure Function
- 0.4: Configure the python webapp project
- 0.5: Run the sample
- 0.6: (optional) deploy frontend web app to Azure
0.1: Create frontend web app
To run this sample, you’ll need to install this locally:
- Python 2.7+ or Python 3+
- An Azure Active Directory (Azure AD) tenant. For more information on how to get an Azure AD tenant, see how to get an Azure AD tenant.
- Git to clone the following project:
git clone https://github.com/rebremer/ms-identity-python-webapp-backend.git
or download and extract the repository .zip file.
0.2: Create and configure app registration
Create and configure an app registration as follows:
- Create an app registration using the steps in this link to create an app registration. Two remarks:
- Use
http://localhost/getAToken
as reply URL. In case you did not do this during creation, it can be added using the Authentication tab of the app registration - Go to Authentication and enable the option ID tokens in Implicit grant
- Go to Certificates & Secrets to create a secret. Copy the client_id and client secret
0.3: Create backend Azure Function
In this part, the Azure Function will be deployed. This is done as follows:
- Create an Azure Function in python using this quickstart.
- Update the
requirement.txt
and__init__.py
from the blog-webappaad-backend folder from the git repo and publish funcion again - Enable Authentication / Authorization in your Azure Function using express settings following this quickstart.
0.4: Configure the pythonwebapp project
- Open the
app_config.py
file and change the variables below. - Find text
<<Enter_the_Client_Secret_here>>
and replace it with your application secret during the creation of the app registration in step 1.2. - Find text
<<Enter_the_Tenant_Name_Here>>
and replace the existing value with your Azure AD tenant name. - Find text
<<Enter_the_Application_Id_here>>
and replace the existing value with the application ID (clientId) of the app registration in step 1.2. - Find text
<<your Azure Function>>
and<<your secret>>
replace the existing value with the Azure Function created in step 1.3.
0.5: Run the sample
You will need to install dependencies using pip as follows:
$ pip install -r requirements.txt
Run app.py from shell or command line using the following command:
flask run --host localhost --port 5000
When the app is run locally, it can be visited by localhost:5000 (not 127.0.0.1:5000). After step 1, users can login using their Azure AD credentials and retrieve data from the backend.
0.6: (optional) deploy frontend web app to Azure
Finally, see this link how to deploy your frontend flask app in an Azure web app. Simplest way to deploy your code is running following command from the directory where app.py is placed:
az webapp up -n <<your unique webapp>> --sku F1
Make sure that https://<<your uniquewebapp>>.azurewebsites.net/getAToken
is added as reply URL. When you login and click on link to retrieve data from backed, the following screen shall be shown:

However, to be able to execute the remaining steps of this tutorial, localhost can be used as well.
Step 1: Access to frontend – AAD login, add roles
In this step, a role is assigned to the user to indicate whether it is a basic user or premium user. The following sub steps are executed:
- 1.1: Set configuration in app config
- 1.2: Add roles to manifest
- 1.3: Assign premium roles to users
Step 1 focusses on the follow part of the architecture.
1.1: Set configuration in app config
Claim verification is an optional step and can be enabled using the following setting in app_config.py
file: AAD_ROLE_CHECK = True
.
1.2: Add roles to manifest
Follow the steps in this tutorial to add roles to app registration created in step 1.2. As manifest, the following appRoles shall be used:
"appRoles": [
{
"allowedMemberTypes": ["User"],
"description": "Basic user, read product data from backend",
"displayName": "basic_user_access",
"id": "a8161423-2e8e-46c4-9997-f984faccb625",
"isEnabled": true,
"value": "basic_user_access"
},
{
"allowedMemberTypes": ["User"],
"description": "Premium user, read all data from backend",
"displayName": "premium_user_access",
"id": "b8161423-2e8e-46c4-9997-f984faccb625",
"isEnabled": true,
"value": "premium_user_access"
}
],
1.3: Assign user to role
The assignment of users is explained in this link. As a test, two users can be created. User 1 is assigned the basic_user_access
, whereas user 2 gets the premium_user_access
role, see also screenshot below in which admin, student2 has an premium role assigned and student 1 only has basic.

In case student clicks on the customer link, access to the backend is denied by the frontend, see also message below.

In the next step, user data is retrieved using the Microsoft Graph API.
Step 2. Access to Graph— Delegated permissons
Users are the representation of an Azure AD work or school user account or a Microsoft account in Microsoft Graph. In this step, the delegated permissions of the signed-in user are used to retrieve its own data using scope users.read
. The following sub steps are executed:
- 2.1: Verify permissions in app registration
- 2.2: Retrieve data
Step 2 focusses on the follow part of the architecture.
2.1: Verify permissions in app registration
The app registration either needs to have consent to read the user data from the Microsoft Graph. Depending on Azure AD configuration, the following types of consent are possible:
- admin consent: An admin has consented that the app can read the user’s data on behalf of the signed-in user. This consent can be done on beforehand in the app registration permissions or when an admin logs in for the first time in the web app.
- user consent: An uses himself has consented that the app can read the user’s data on behalf of the signed-in user. This consent is done once a user logs in for the first time in the app
In this case, admin consent is used that is done on beforehand. See below the users.read permission is granted in app registration:

Subsequently, verify in the adhering Enterprise Application of App registration that app can read user’s data on behalf of the user.

Notice that User.Read only allows a user to retrieve his own data and not data of others (that can only be done with permission User.Read.All)
2.2: Retrieve Graph data
Once the app has either user consent of admin consent to retrieve data, just log in and click on the link Call Microsoft Graph API and user’s own data is returned, see also below.

Step 3. Access to backend – Applications permissions
In step 1, data was already retrieved from the backend. However, not only the frontend can retrieve data from the backend, but all identities within the same Azure AD tenant can retrieve data. Using application permissions and user assigment, it is made sure that only the frontend can access the backend.
The following sub steps are executed:
- 3.1: Add application permissions to backend and frontend
- 3.2: Enable user assignment in backend
Step 3 focusses on the follow part of the architecture.
3.1: Add application permissions to backend and frontend
Go to the manifest of your backend app registration and add the following app role to the manifest.
"appRoles": [
{
"allowedMemberTypes": ["Application"],
"description": "frontend_app_access",
"displayName": "frontend_app_access",
"id": "f8161423-2e8e-46c4-9997-f984faccb625",
"isEnabled": true,
"value": "frontend_app_access"
},
Subsequently, go to the app registration of the frontend, click API permissions and grant these permissions to your frontend app, see also below.

Subsequently, grant admin permissions such that frontend can access backend with application role front_end_access. To verify whether frontend has application role front_end_access, go to your backend app registration, Enterprise Application and look for users/groups, see also below.

Notice that role front_end_access is not explicitely shown, but it will be shown in 3.2 that role is there.
3.2: Enable user assignment in backend
Go to your backend app registration, Enterprise Application and look for Properties and enable user assignement, see also below.

When this property is enabled, the frontend is the only application that can retrieve data from the backend, see also below where role is displayed

Miscellaneous
The git repo belonging to this project has additional configuration options that are discusssed below:
- By setting
DAEMON_ENABLED=True
in the appconfig, the application can be configured as daemon application. User does not have to login anymore to retrieve data. - By setting
Option 2b. Database
in the appconfig, an Azure SQL database can be used as backend rather than an Azure Function. See this blog for details on this. - With
Option 3b. Delegated user is used to authenticate to backend
in the app config, delegated permissions are used to authenticate to backend rather than application permissions. - Step 3 in this blog can be automated by adjusting the Power Shell script in this git repo.
Conclusion
The Microsoft identity platform can help you to secure access to your applications. In this blog, a concrete example is provided that uses Azure AD to login users with either user role "basic" or "premium". Subsequently, delegated permissions of signed-in users are used to retrieve Microsoft Graph data and application permissions are used to access the backend, see also architecture below.
