Read Roles in blazor WebAssembly (hosted) App

Well, I just did it. I have to add .AddAccountClaimsPrincipalFactory< ArrayClaimsPrincipalFactory<RemoteUserAccount>>(); to OidcAuthentication. So the final code in Program.cs in Client side is:

builder.Services.AddOidcAuthentication(options =>
        {
            builder.Configuration.Bind("Auth0", options.ProviderOptions);
            options.ProviderOptions.ResponseType = "code";

        }).AddAccountClaimsPrincipalFactory<
ArrayClaimsPrincipalFactory<RemoteUserAccount>>();

Also I added this code:

public class ArrayClaimsPrincipalFactory<TAccount> : AccountClaimsPrincipalFactory<TAccount> where TAccount : RemoteUserAccount
{
    public ArrayClaimsPrincipalFactory(IAccessTokenProviderAccessor accessor)
    : base(accessor)
    { }


    // when a user belongs to multiple roles, IS4 returns a single claim with a serialised array of values
    // this class improves the original factory by deserializing the claims in the correct way
    public async override ValueTask<ClaimsPrincipal> CreateUserAsync(TAccount account, RemoteAuthenticationUserOptions options)
    {
        var user = await base.CreateUserAsync(account, options);

        var claimsIdentity = (ClaimsIdentity)user.Identity;

        if (account != null)
        {
            foreach (var kvp in account.AdditionalProperties)
            {
                var name = kvp.Key;
                var value = kvp.Value;
                if (value != null &&
                    (value is JsonElement element && element.ValueKind == JsonValueKind.Array))
                {
                    claimsIdentity.RemoveClaim(claimsIdentity.FindFirst(kvp.Key));

                    var claims = element.EnumerateArray()
                        .Select(x => new Claim(kvp.Key, x.ToString()));

                    claimsIdentity.AddClaims(claims);
                }
            }
        }

        return user;
    }
}
3 Likes