Search code examples
blazorblazor-client-sideblazor-webassemblyasp.net-blazor

Create claims for a Blazor WebAssembly project


I use the default Blazor WebAssembly template to create a project using the “individual user accounts option” and I try to create a custom claim when the user login and access it from the Blazor client side but I have not managed to make it work.

I know that I will have to create a custom authentication state provider for the Blazor client project but after several hours trying to make it work, I have not found a solution to my problem.

Can someone give me some tips of how to implement it?


Solution

  • In Program.cs

    builder.Services.AddApiAuthorization()
        .AddAccountClaimsPrincipalFactory<CustomAccountClaimsPrincipalFactory>();
    

    CustomAccountClaimsPrincipalFactory.cs

    public class CustomAccountClaimsPrincipalFactory
        : AccountClaimsPrincipalFactory<RemoteUserAccount>
    {
        private const string Planet = "planet";
    
        public CustomAccountClaimsPrincipalFactory(IAccessTokenProviderAccessor accessor)
            : base(accessor) { }
    
        public async override ValueTask<ClaimsPrincipal> CreateUserAsync(
            RemoteUserAccount account,
            RemoteAuthenticationUserOptions options)
        {
            var user = await base.CreateUserAsync(account, options);
    
            if (user.Identity.IsAuthenticated)
            {
                var identity = (ClaimsIdentity)user.Identity;
                var claims = identity.Claims.Where(a => a.Type == Planet);
                if (!claims.Any())
                {
                    identity.AddClaim(new Claim(Planet, "mars"));
                }
            }
            return user;
    
        }
    
    }
    
    
    

    ClaimDisplay.razor

    @using System.Linq
    @using System.Threading.Tasks
    @using Microsoft.AspNetCore.Components
    @using Microsoft.AspNetCore.Components.Authorization
    
    @ClaimType: @Claim
    @code {
        [Inject]
        AuthenticationStateProvider AuthenticationStateProvider { get; set; }
    
        [Parameter]
        public string ClaimType { get; set; }
    
        public string Claim { get; set; }
    
        protected override async Task OnInitializedAsync()
        {
            var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
            var user = authState.User;
            if (user.Identity.IsAuthenticated)
            {
                var userClaims = user.Claims.Where(claim => claim.Type.Equals(ClaimType));
                Claims = userClaims.Any() ? userClaims.Select(claim => claim.Value).Aggregate(AddClaims) : "";
            }
        }
    
        private static string AddClaims(string left, string right) => left + ", " + right;
    }
    

    usage:

    <ClaimDisplay ClaimType="planet" />
    
    

    Working demo