Overview
This article will discuss a minimum complex design if you have several SPA Apps or other Apps that call a global API . This design is future proof for when you later need to introduce an API gateway, since an API gateway uses a similar concept of 1 access token for all API’s.
If you have a new in house client app that requires AAD integration for Authentication and Authorization and your apps are all exposed within your organisation network only.
Anyone in the organisation can create apps, however it is important to adhere to some conventions, expecially if you want to reduce the costs around onboarding new apps and the administrative overhead.
If you can affort it, I would recommend https://www.okta.com/ , currently AAD still has a far higher OPEX cost associated with the day to day operations regarding Identity Management versus Azure AD. So lets get started with the Implicit Grant Flow for SPA Apps. Hopefully Microsoft will support the Code Authorization with PKCE for SPA’s soon.
Diagram showing the Implciti Grant Flow in an AAD environment

Design
- App registrations need to be created per environment (Dev, QA, UAT, Prod).
- All physical API’s you host are linked to 1 App Registration in AAD (Same Audience)
- All Clients have their own App registration using the API Audience
- API exposes a default scope – Later when you implement an API gateway SCOPE logic can reside on the gateway. This keeps the design future proof.
This is for SPA apps that use Implicit Grant Flow. AAD currently only supports this flow for SPA apps; otherwise Code Authorization Flow with PKCE is superior, which OKTA supports 🙂
- Users are added to Azure AD Groups
- 1 Global API App Registration per environment (Global API)
- Application Roles are ONLY created in the Global API APp registration
- AD Groups are assigned to Application Roles
Diagram Illustration the AAD Relationship in this design. We only support 1 Audience (The Global API).

Diagram illustrating the AAD implementation Stategy regarding Users, Groups, Apps and Application Roles (API)

Implicit Grant SPA ->Global API
Prerquisite – You already have a Global API App Registration that exposes an API in AAD.
- Go to the Azure Portal
- Click “App Registrations”Click “New Registration”
- Provide a name that adheres to the convention – Department <env> <AppName>SPA
- Once the app is created
- Go to the Branding Blade and ensure the Domain is verified and select your domaiun name.
- Add any custom branding e.g. LogoClick Authentication Blade
- Enable Implicit Grant Flow by ticking – ID Token, Access Token
- Record the APP ID by clicking Overview and copying the Application (client) ID
If you do not want a consent dialog to show when the user uses the app. You need to add your shiny new app to the Global API app as a trusted application. Each environment has a GLOBAL API e.g. Department <envcode> API
Navigate to Department<envcode> API
Click “Expose an API
”Click “Add a client Application”
There is another method to add API permissions via the SPA App instead of trusted clients, however this required Global Tenant Admin grants.
- Add the API’s in the API Permissions blade then
- Click the Grant/revoke admin consent for XYZ Company Limited button, and then select Yes when you are asked if you want to grant consent for the requested permissions for all account in the tenant. You need to contact an Azure AD tenant admin to do this.
You are now ready to use your new APP for Authentication.Update your code base to use a supported OAuth2.0 and OpenID library e.g. MSAL.JS
https://docs.microsoft.com/en-us/azure/active-directory/develop/reference-v2-librariesEnsure you are compliant e.g. Tokens are being verified
- All Access Tokens provided by the Global API are valid for 1 hour. You will need to refresh the token for a new one. The library will do this for you.
- Ensure all Tokens are Verified on the SPA side (ID Token and Access Token)
- NEVER send the ID Token to the API. Only the Access Token (Bearer)
- AVOID storing the access token in an insecure storage location
Global API Manifest (Global API App Registration)
- Create your Global API
- Ensure the Branding is correct
- Expose an API e.g. default
- Add Trusted Client Apps like the SPA above
- Edit the Manfiest to include any Application or User Roles. Application Roles are great for service to service communication which is not covered in this article.
Here is where you define roles in the app manifest on the Global API App.
"appRoles": [
{
"allowedMemberTypes": [
"User"
],
"description": "Standard users of MyApp1 SPA.",
"displayName": "MyApp1-Payroll",
"id": "12343b9d-2e21-4ac3-b3cd-f0227588fc03",
"isEnabled": true,
"lang": null,
"origin": "Application",
"value": "MyApp1-Payroll"
},
...
Your API will implement RBAC based on the App Roles defined in the Global API Manifest. In AAD Portal, add additional App Roles
[Authorize(Roles = "Manager")]
public class ManagerController : Controller
{
}
[Authorize(Roles = "Administrator")]
public class AdministrationController : Controller
{
}
public class HomeController : Controller
{
}
//Policy based
[Authorize(Policy = "AtLeast21")]
public class AlcoholPurchaseController : Controller
{
public IActionResult Index() => View();
}
Ensure you are using Microsoft Identity V2!
This design will provide the least amount of administrative overhead for apps that need to be publish internally within the organisation and provides a decent level of security coverage.
- Uncategorized