Alexander
Alexander

Reputation: 126

Roles/Groups Azure Active Directory and access them with Blazor WASM AuthorizeView

Hey Login and Logout works as expected.

I have created roles in the App registration.

enter image description here

In the Manifest I have changed groupMembershipClaims from null to "All"

"groupMembershipClaims": "All",

Those roles have been assigned to me (Alex) and to 2 created groups (enterprise application screenshot):

enter image description here

Programm.cs / Added options.UserOptions.RoleClaim = "appRole"

  builder.Services.AddMsalAuthentication(options =>
    {
        builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
        options.ProviderOptions.DefaultAccessTokenScopes
            .Add("https://graph.microsoft.com/User.Read");
        options.ProviderOptions.LoginMode = "redirect";
        options.UserOptions.RoleClaim = "appRole";
    });
    

When I try to access them, for example with: Roles="dog_cc_ma"

@page "/"
@inject Microsoft.Extensions.Localization.IStringLocalizer<ResourceFiles.Resource> localizer
@attribute [Authorize]

<h1>@localizer["helloworld"]!</h1>

<AuthorizeView>
    <Authorized>
        Hello, @context.User.Identity?.Name! <br />
        @context.User.Identity?.AuthenticationType;
           <ul>
                <li>@foreach (var claim in context.User.Identities)
                {<ul>
                    <li>@claim.RoleClaimType</li>
                    <li>@claim.AuthenticationType</li>
                    <li>@claim.Actor</li>
                    <li>@claim.NameClaimType</li>
                    <li>@claim.Label</li>
                </ul>
                }
                </li>
            </ul> 
    </Authorized>
    <NotAuthorized>
  
    </NotAuthorized>
</AuthorizeView>

<AuthorizeView Roles="admin, superuser, owner">
    <p>You can only see this if you're an admin or superuser.</p>
    Hello, @context.User.Identity?.Name! <br />
</AuthorizeView>
<AuthorizeView Roles="dog_cc_ma">
    <p>You can only see this if you have a dog insurance.</p>
    Hello, @context.User.Identity?.Name! <br />
</AuthorizeView>
<AuthorizeView Roles="travel_cc_ma">
    <p>You can only see this if you have a travel insurance.</p>
    Hello, @context.User.Identity?.Name! <br />
</AuthorizeView>

It doesn't work, anyone know why....?

claim.loop

enter image description here

Best, Alex

Upvotes: 1

Views: 645

Answers (1)

Alexander
Alexander

Reputation: 126

SOLUTION

Add 2 classes and 1 extra to Program.cs, than it works.

RemoteUserAccount.cs

public class CustomUserAccount : RemoteUserAccount
    {
        [JsonPropertyName("roles")]
        public string[] Roles { get; set; } = Array.Empty<string>();

    }

CustomAccountFactory.cs

public class CustomAccountFactory
: AccountClaimsPrincipalFactory<CustomUserAccount>
{
    private readonly ILogger<CustomAccountFactory> logger;
    private readonly IServiceProvider serviceProvider;

    public CustomAccountFactory(IAccessTokenProviderAccessor accessor,
        IServiceProvider serviceProvider,
        ILogger<CustomAccountFactory> logger)
        : base(accessor)
    {
        this.serviceProvider = serviceProvider;
        this.logger = logger;
    }
    public async override ValueTask<ClaimsPrincipal> CreateUserAsync(
        CustomUserAccount account,
        RemoteAuthenticationUserOptions options)
    {
        var initialUser = await base.CreateUserAsync(account, options);

        if (initialUser.Identity.IsAuthenticated)
        {
            var userIdentity = (ClaimsIdentity)initialUser.Identity;

            foreach (var role in account.Roles)
            {
                userIdentity.AddClaim(new Claim("appRole", role));
            }
        }

        return initialUser;
    }
}

Program.cs

builder.Services.AddMsalAuthentication <RemoteAuthenticationState,
                 CustomUserAccount > (options =>
            {
                builder.Configuration.Bind("AzureAd", options.ProviderOptions.Authentication);
                options.ProviderOptions.DefaultAccessTokenScopes
                    .Add("https://graph.microsoft.com/User.Read");
                options.ProviderOptions.LoginMode = "redirect";
                options.UserOptions.RoleClaim = "appRole";
            }).AddAccountClaimsPrincipalFactory<RemoteAuthenticationState, CustomUserAccount,
             CustomAccountFactory>();

Upvotes: 2

Related Questions