Microsoft EntraID Apps for SPA and WEB API

This tutorial will register Microsoft EntraID applications (SPA and WEB_API) for OIDC authorization code flow with PKCE.

SPA (single-page application) is a public page that can sign in to users with Microsoft identity accounts and call backend WEB API service using bearer token with delegated scope issued to authenticated users to authorize API access. The SPA - is usually built using JS/Angular/React framework with Microsoft Authentication Library (MSAL), which supports authorization code flow in the browser instead of the implicit grant flow. WEB API - can be built using ASP.NET Core framework with "Microsoft.Identity.Web" authentication library, which can protect the API, check permissions and validate Azure Identity tokens for access.


The diagram shows how OIDC flow works between apps 

Elaboration on the above steps:

EntraID Apps Registration

Two Azure EntraID applications must be registered. One for SPA (web-msal-spa) and another for WEB API (web-msal-api)

Register backend API service app (web-msal-api)

Publish Delegated Permissions


Publish Application Permissions

1.     All APIs should publish a minimum of one App role for applications, also called Application Permission, for the client apps to obtain an access token as themselves, i.e. when they are not signing-in a user. Application permissions are the type of permissions that APIs should publish when they want to enable client applications to successfully authenticate as themselves and not need to sign-in users. To publish an application permission, follow these steps:

2.     Still on the same app registration, select the App roles blade to the left.

3.     Select Create app role:

1. For Display name, enter a suitable name : JWT.Read.All.

2. For Allowed member types, choose Application to ensure other applications can be granted this permission.

3. For Value, enter JWT.Read.All.

4. For Description, enter : Allows the app to read the signed-in user's JWT data.

5. Select Apply to save your changes.

6. ⚠️ Repeat the steps above for another app permission named JWT.ReadWrite.All

Configure Optional Claims

1.     Still on the same app registration, select the Token configuration blade to the left.

2.     Select Add optional claim:

1. Select optional claim type, then choose Access.

2. Select the optional claim idtyp. (Indicates token type. This claim is the most accurate way for an API to determine if a token is an app token or an app+user token. This is not issued in tokens issued to users.)

3.         Select Add to save your changes. 

Register the client app (web-msal-spa)

1.     Navigate to the Azure portal and select the Microsoft Entra ID service.

2.     Select the App Registrations blade on the left, then select New registration.

3.     In the Register an application page that appears, enter your application's registration information:

1. In the Name section, enter a meaningful application name: web-msal-spa

2. Under Supported account types, select Accounts in this organizational directory only

3. Select Register to create the application.

4.     In the app's registration screen, select the Authentication blade to the left.

5.     If you don't have a platform added, select Add a platform and select the Single-page application option.

1. In the Redirect URI section enter the following redirect URI (This is a temporary development URI


2.     Select Configure

3. Click Add URI and update list with additional bellow URIs (The list will need to be updated with FQDNs where you will run SPA too):


4. Select Save to save your changes.

6.     Since this app signs-in users, we will now proceed to select delegated permissions, which is is required by apps signing-in users.

1. In the app's registration screen, select the API permissions blade in the left to open the page where we add access to the APIs that your application needs:

2. Select the Add a permission button and then:

3. Ensure that the Microsoft APIs tab is selected.

4. In the Commonly used Microsoft APIs section, select Microsoft Graph

5. In the Delegated permissions section, select openid, offline_access in the list. Use the search box if necessary.

6. Select the Add permissions button at the bottom.

7. Select the Add a permission button and then:

8. Ensure that the APIs my organization uses tab is selected.

9. In the list of APIs, select the API web-msal-api

10.  In the Delegated permissions section, select JWT.Read, JWT.ReadWrite in the list. Use the search box if necessary.

11.  Select the Add permissions button at the bottom.

7.     At this stage, the permissions are assigned correctly. To avoid consent prompts for users or access promts, let the tenant administrator consent on behalf of all users in the tenant for API permissions. Select the Grant admin consent for {tenant} button, and then select Yes when you are asked if you want to grant consent for the requested permissions for all accounts in the tenant. You need to be a tenant admin to be able to carry out this operation.


Postman OIDC Flows Testing

You can test the OIDC Flows using the "Postman" application. You can set Authorization on the "Postman" collection or Rest API. 

The following configuration needs to be used:

 Type: Oauth 2.0

Add auth data to: Request Headers

Token: OIDC

Header Prefix: Bearer

Auth URL:{YourAzureEntraTenantID}/oauth2/v2.0/authorize

Access Token URL:{YourAzureEntraTenantID}/oauth2/v2.0/token

Client ID: {ClientID-web-msal-spa}

Code Challenge Method: SHA-256

Scope: api://{ClientID-web-msal-api}/JWT.Read api://{ClientID-web-msal-api}/JWT.ReadWrite

Client Authentication: Send client credentials in body

Refresh Token URL:{YourAzureEntraTenantID}/oauth2/v2.0/token

Token Request: Key=Origin Value=http://localhost:3000/ Sendin = Request Headers

Refresh Request: Key=Origin Value=http://localhost:3000/ Sendin = Request Headers

Get Access Token

After clicking Get New Access Token, you should see the success message "Authentication completed" and click the process button. (Make sure your browser is not blocking pop-ups).  You will see a valid Access token, which you can use to access the WEB API backend protected with the web-msal-api application. 

Decode Access Token

Using the JSON Web Tokens decoder, you can decode base64 access token data. If successful, you should see the audience (AUD) is web-meal-API ClientID information and scopes (SCP) configured as part of the app's configuration.