Simple role based authorization with Microsoft Entra ID in ASP.NET Core using App Roles

App Roles are a very simple way to add role based authorization to your app when using Microsoft Entra ID (formerly known as Azure Active Directory) as identity provider.

Philipp Bauknecht
Published in
5 min readNov 16, 2023

--

This blog post describes steps required to configure and implement role based authorization using the Microsoft Identity Platform. We’re going to

  • Configure Authentication and Authorization in Microsoft Entra ID
  • Build simple ASP.NET Core Minimal API app that’s secured both with authentication and app role based authorization
  • Authenticate in Postman by creating a new OAuth2 access token to test the API

Prerequisites

Make sure you have the following things at hand/installed:

Configure App Registration

To create add authentication and authorization using Microsoft Entra ID for any app as well as to create app roles it’s necessary to create an App Registration in Entra ID first. This can be done either by in the Azure Portal or by using the Microsoft Graph API e.g. through PowerShell.

Let’s start by signing in. It’s important to use the right scope to be able to do the desired operations. In our case we want to create a new Application Registration:

Connect-MgGraph -Scopes "Application.ReadWrite.All"

Our App Registration needs a bit of configuration for our use case so let’s define some variables for those. The first one defines a redirect Uri that we want to use later when authenticating though Postman:

$publicClientApplication = @{
RedirectUris=@("https://oauth.pstmn.io/v1/callback")
}

We also need to define a minimum of one scope that can be requested access to when authenticating. Therefore we need to define the identifier Uri for our application as well as the scope itself:

$identifierUris = @("api://myapp")
$apiApplication = @{
Oauth2PermissionScopes = @(
@{
Id=$(New-Guid)
Value="full"
AdminConsentDescription="Full Access"
AdminConsentDisplayName="Full Access"
IsEnabled=$true
Type="User"
UserConsentDescription="Full Access"
UserConsentDisplayName="Full Access"
}
)
}

Now we can describe the app roles, e.g. Admin and Contributor:

$appRoles = @(
@{
Id=$(New-Guid)
Value="admin"
DisplayName="Administrator"
Description="Administrators can manage everything"
AllowedMemberTypes=@("User")
}
@{
Id=$(New-Guid)
Value="contributor"
DisplayName="Contributor"
Description="Contributors can write and read data"
AllowedMemberTypes=@("User")
}
)

With the configuration defined as variables we can proceed to create the actual app registration:

$application = New-MgApplication `
-DisplayName 'MyApp' `
-SignInAudience 'AzureADMyOrg' `
-PublicClient $publicClientApplication `
-IdentifierUris $identifierUris `
-Api $apiApplication
-AppRoles $appRoles `

To be able to assign users later to the app roles we also need to create a service principal for the application registration:

$servicePrincipalId=@{ "AppId" = $application.AppId }
New-MgServicePrincipal -BodyParameter $servicePrincipalId

Assign roles to users

To assign users to app roles a different set of scopes is needed when signing in in PowerShell:

Connect-MgGraph -Scopes "AppRoleAssignment.ReadWrite.All,User.ReadWrite.All"

To create new app role assignments we need the user id of the user to assign to, the id of the app role and the id of the service principal. So let’s look them up. First lets retrieve the newly created application registration:

$application = Get-MgApplication -Filter "DisplayName eq 'MyApp'"

In there we can find the app role and it’s id:

$adminAppRoleId = $($application.AppRoles | where {$_.value -eq "admin"}).Id

The same way we can also look up the service principal:

$servicePrincipal = Get-MgServicePrincipal -Filter "DisplayName eq 'MyApp'")

We the Ids at hand we can now create the app role assignment:

$userId = "{YOUR_USER_GUID}"
New-MgUserAppRoleAssignment `
-UserId $userId `
-AppRoleId $adminAppRoleId `
-PrincipalId $userId `
-ResourceId $servicePrincipal.Id

Build the demo API app

So now it’s time to build a simple ASP.NET Core Minimal API app and secure it using the open source Microsoft.Identity.Web library which is part of the Microsoft Identity Platform. So let’s create a new project and add Microsoft.Identity.Web from Nuget.

Configure Entra ID

To use the newly create Application Registration with our app we need to provide some configuration values in the appsettings.json of our project:

{
"AzureAd": {
"Instance": "https://login.microsoftonline.com/",
"TenantId": "{YOUR_TENANT_ID}",
"ClientId": "{YOUR_APPLICATION_CLIENT_ID}",
"Audience": "api://MyApp"
}
}

Add authentication

To add authentication we need to include a using statement for Microsoft.Identity.Web. Then we can add the authentication service from that library and configure it using the configuration we just added in appsettings.json by referencing the “AzureAD” object. Finally we also need to use the authentication:

using Microsoft.Identity.Web;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddMicrosoftIdentityWebApiAuthentication(builder.Configuration, "AzureAd");

var app = builder.Build();

app.UseAuthentication();

app.Run();

Add role based authorization

This is the fun part: We leverage app roles by creating a new policy for every role we created in the App Registration:

builder.Services.AddAuthorization(options =>
{
options.AddPolicy("admin", policy => policy.RequireRole("admin"));
options.AddPolicy("contributor", policy => policy.RequireRole("contributor"));
});

Add and secure endpoints

With authentication and authorization configured in our app we can create two sample endpoints and protect them by referencing the policies we just created:

app.MapGet("/", () =>
{
return "Hello World";
}).RequireAuthorization("contributor");

app.MapPost("/", () =>
{
return "Hello World";
}).RequireAuthorization("admin");

It’s as simple as that!

Use Postman for testing

Finally we use Postman to test our API endpoints. Since those are protected we need to sign in first in Entra ID, acquire an OAuth2 access token and use this in the authorization header of our http requests.

Let’s create a new request in Postman and configure a new token in Authorization > Type: OAuth 2.0 :

For Auth URL use: https://login.microsoftonline.com/{YOUR_TENANT_ID}/oauth2/v2.0/authorize

For Access Token URL use: https://login.microsoftonline.com/{YOUR_TENANT_ID}/oauth2/v2.0/token

Click on “Get New Access Token” to sign in. After successful signin we can view and use the access token:

With the token acquired we can now call our demo app locally and test if roles are enforced correctly.

Conclusion

App Roles in Microsoft Entra ID provide an easy way to implement role based authorization for simple scenarios. The Microsoft Identity Platform with it’s open source libraries make it simple to implement authentication and authorization to protect APIs in ASP.NET Core. Postman can be used it request OAuth 2.0 access tokens from Microsoft Entra ID facilitating testing protected APIs.

--

--

Philipp Bauknecht

CEO @ medialesson. Microsoft Regional Director & MVP Windows Development. Father of identical twins. Passionate about great User Interfaces, NYC & Steaks