MSAL: Blazor Server client with AspNetCore API. Both protected by MSAL. How to have client access user's API roles?

46 Views Asked by At

We are building an internal application protected by MSAL. We currently have two app registrations and two programs. A blazor server client application and an aspnetcore web api. We are using App Roles assigned to the API app registration inside of Azure. Both .Net 8.

The client setup:

    builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration)
                .EnableTokenAcquisitionToCallDownstreamApi()
                .AddInMemoryTokenCaches();
    builder.Services.AddAuthorization(options =>
    { options.FallbackPolicy = options.DefaultPolicy; });

The web api setup:

    builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddMicrosoftIdentityWebApi(builder.Configuration.GetSection(Constants.AzureAd));
    builder.Services.AddAuthorization(config =>
    {
    config.AddPolicy("AuthZPolicy", policyBuilder => policyBuilder.Requirements.Add(new ScopeAuthorizationRequirement() { RequiredScopesConfigurationKey = $"AzureAd:Scopes" }));
    });

The client can call the API by passing an authorization header from the IAuthorizationHeaderProvider to the HttpClient calls:

    var authorizationHeader = await _authorizationHeaderProvider.CreateAuthorizationHeaderForUserAsync(_scopes);
    client.DefaultRequestHeaders.Add("Authorization", authorizationHeader);

That all works great as expected.

What is the proper way to get the client to be aware of what roles to the API the user has? I.e., admin users may need to see different items on the client side than non-admin users. Or, if user has none of our app roles, we want to bring them to a specific page.

I've been searching for the correct way to do this for a while, but unable to find a solid answer. There are a few avenues but to an extent, they all seem more complicated than one would expect.

A way we've tried and know will "work": Use the authorization header, take the token from it, deserialize, and parse out the app roles.

We could also mirror the App Roles in both the client and the api app registrations in Azure, but that brings maintenance concerns and also feels incorrect.

Curious to see what others have found, tried, and ended up going with? Or if there is a proper way to achieve this?

0

There are 0 best solutions below