0
votes

I would like to use Azure AD for authentication and want to use custom role based authorization in angular 7 and .Net Core Web api. I was able to successfully authenticate user using Azure AD with msal, however for authorization I have to use roles defined into database. I also need to pass role in token back to angular app so that I can use role on angular side as well.

1

1 Answers

2
votes

In Azure AD , you can use add app roles in your application , and then assign users and groups to roles , so that after user login , roles cliam will exist in tokens :

https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-add-app-roles-in-azure-ad-apps

Another approach is to use Azure AD Groups and Group Claims :

https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-fed-group-claims

But if your roles information are maintained in local database , after user login with AAD with MSAL in angular application , you can query database and get user's roles by user id , when performing api calls, you can send roles in request body .

If you don't want to query the roles in client application , when sending access token to .net core web api , you can query the database to get the user's roles in OnTokenValidated event of AddJwtBearer :

services
    .AddAuthentication(o =>
    {
        o.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(o =>
    {
        //Additional config snipped
        o.Events = new JwtBearerEvents
        {
            OnTokenValidated = async ctx =>
            {
                //Get the calling app client id that came from the token produced by Azure AD
                string clientId = ctx.Principal.FindFirstValue("appid");

                //Get EF context
                var db = ctx.HttpContext.RequestServices.GetRequiredService<AuthorizationDbContext>();

                //Check if this app can read confidential items
                bool canReadConfidentialItems = await db.Applications.AnyAsync(a => a.ClientId == clientId && a.ReadConfidentialItems);
                if (canReadConfidentialItems)
                {
                    //Add claim if yes
                    var claims = new List<Claim>
                    {
                        new Claim("ConfidentialAccess", "true")
                    };
                    var appIdentity = new ClaimsIdentity(claims);

                    ctx.Principal.AddIdentity(appIdentity);
                }
            }
        };
    });

Reference : https://joonasw.net/view/adding-custom-claims-aspnet-core-2

After that you can pass the roles back to client in request body , but you can't modify the Azure AD token to include roles information .

If you are concern about the security that passing roles in request body , you can also use Identity Server 4 and add Azure AD as external login provider :

http://docs.identityserver.io/en/latest/