Search code examples
c#asp.net-coreauthenticationblazorclaims-based-identity

Inject custom created object based on claims


I'm using claims based authentication in my Blazor Server app. When the user logs in to my app, I define a claim which contains a specific ID to identify the user within the database.

Now I want to get an object based on its value which I can use within my app.

For example: let's say the value from my claim is 1. Now I need a way to get the data for user 1 from the database and inject the object into my razor components/pages to make all properties accessible at any time within my app. I think this can be achieved with some sort of middleware but I'm not sure about this.

My current approach is to access the HttpContext within the _Host.cshtml file which loads the appropriate data to the page on a page reload but not when changing pages using a NavLink or the NavigationManager.

How can I get the relevant data to load each time the active page is changed?


Solution

  • I tried to adjust @Hans code but by using AuthenticationStateProvider

    using System.Security.Claims
    using Microsoft.AspNetCore.Components.Authorization
    
    public class ClaimsPrincipalDataService
    {
        private readonly AuthenticationStateProvider AuthenticationStateProvider;
        private readonly DbContext DbContext;
    
        public ClaimsPrincipalDataService(AuthenticationStateProvider AuthenticationStateProvider , DbContext DbContext)
        {
            this.AuthenticationStateProvider  = AuthenticationStateProvider;
            this.DbContext = DbContext;
        }
    
        private async Task<User> GetUserAsync()
        {
           var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
            var user = authState.User;
          if (user.Identity.IsAuthenticated)
            {
                var userId = user.FindFirst(ClaimTypes.NameIdentifier).Value;
               return await DbContext.Users.FindAsync(userId);
            }
            else
            {
                //do something
            }
        }
    }
    

    Add scope

    services.AddScoped<ClaimsPrincipalDataService>();

    Inject the service in your component

    @inject ClaimsPrincipalDataService ClaimService
    
    @code {
        private User _user;
    
        protected override async Task OnInitializedAsync()
        {
            _user = await ClaimService.GetUserAsync();
        }
    }