4

hello community I have a question how can I use usermanager in a blazor page webassembly ? by injecting this:

@inject UserManager<ApplicationUser> UserManager;

I get the indication that a usage directive is missing as the class the ApplicationUser class is on the server and the client does not have access to the server.

this is my code in blazor page:

@page "/index"
@inject AuthenticationStateProvider AuthenticationStateProvider
@using Microsoft.AspNetCore.Identity;
@inject UserManager<ApplicationUser> UserManager;

<button @onclick="@LogUsername">Write user info to console</button>
<br />
<br />
@Message

@code {
    string Message = "";

    private async Task LogUsername()
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity.IsAuthenticated)
        {
            var currentUser = await UserManager.GetUserAsync(user);
            Message = ($"{user.Identity.Name} is authenticated.{ currentUser.Nombre }");
        }
        else
        {
            Message = ("The user is NOT authenticated.");
        }
    }
}

This is my class ApplicationUser:

    public class ApplicationUser: IdentityUser
        {
            public string Nombre { get; set; }
            public string ApellidoPaterno { get; set; }
            public string ApellidoMaterno { get; set; }
            public virtual Cliente InquilinoActual { get; set; }
        }

Image of an SQL Query

Alenros
  • 816
  • 7
  • 23
Enrique
  • 79
  • 2
  • 11

1 Answers1

5

You can't use UserManager from WebAssembly Blazor app as it is running on the browser. Generally speaking, you can't use objects related to database access in WebAssembly Blazor app. Instead you usually create a Web Api action methods, and access these methods using Fetch API (HttpClient).

What value do you want to extricate from the User object ?

What is Nombre?

No matter what is Nombre, you can add this value (Nombre) as a claim and access it from authState.User

UPDATE

First off, you should create a service class named ApplicationUserClaimsPrincipalFactory which is used to transform table columns' value from the Users table into claims that are added to the ClaimsPrincipal object passed to the Blazor client.

(server application) ApplicationUserClaimsPrincipalFactory.cs

using AuthenticationStateProviderCustomClaims.Server.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;


public class ApplicationUserClaimsPrincipalFactory : 
                       UserClaimsPrincipalFactory<ApplicationUser>
    {
        public ApplicationUserClaimsPrincipalFactory(UserManager<ApplicationUser> userManager, 
                                  IOptions<IdentityOptions> optionsAccessor) : base(userManager, optionsAccessor)
        {
        }

        protected override async Task<ClaimsIdentity> 
                 GenerateClaimsAsync(ApplicationUser user)
        {
            ClaimsIdentity claims = await 
                            base.GenerateClaimsAsync(user);

            
            claims.AddClaim(new Claim("name", user.Nombre));
            
            return claims;
        }
        
    }

Startup.ConfigureServices

put the following below the .AddDBContext:

services.AddScoped<ApplicationUserClaimsPrincipalFactory>();

            services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddClaimsPrincipalFactory<ApplicationUserClaimsPrincipalFactory>();

services.AddIdentityServer() .AddApiAuthorization<ApplicationUser, ApplicationDbContext>(options => {

  // Note: This settings may be superfluous as the name claim 
  // is added by default.              
  options.IdentityResources["openid"].UserClaims.Add("name"); 
  options.ApiResources.Single().UserClaims.Add("name");  

          });

  services.AddAuthentication().AddIdentityServerJwt();

Client Side

Run this code and see if its working...If not please post complete report of the errors

Index.razor

@page "/"

@using System.Security.Claims
@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider

<p>@_authMessage</p>

@if (_claims != null && _claims.Count() > 0)
{
    <ul>
        @foreach (var claim in _claims)
        {
            <li>@claim.Type: @claim.Value</li>
        }
    </ul>
}

<p>@_nombreMessage</p>


@code {
    private string _authMessage;
    private string _nombreMessage;
    private IEnumerable<Claim> _claims = Enumerable.Empty<Claim>();

    private async Task GetClaimsPrincipalData()
    {
        var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity.IsAuthenticated)
        {
            _authMessage = $"{user.Identity.Name} is authenticated.";
            _claims = user.Claims;
            _nombreMessage =
            $"Nombre: {user.FindFirst(c => c.Type == ClaimTypes.Name)?.Value}";
        }
        else
        {
            _authMessage = "The user is NOT authenticated.";
        }
    }
    protected override async Task OnInitializedAsync()
    {
        await GetClaimsPrincipalData();
    }
}
enet
  • 41,195
  • 5
  • 76
  • 113
  • ok very good thank you very much for that information, I wanted to extract from the ApplicationUser the name in my app is different from the UserName – Enrique Dec 21 '20 at 17:55
  • how to use and inject claims in blazor page ? – Enrique Dec 21 '20 at 18:04
  • You first must tell me what Nombre stands for, and in what database table(s) it may be found ... – enet Dec 21 '20 at 18:14
  • in the aspnetuser table you can find the name property, it is the name of the user when registering, I ask for his name and surname, with user.Identity.Name I get the UserName field from the aspnetuser table but I want the Name property that I i included in aspnetuser table, edit my question with an image – Enrique Dec 21 '20 at 18:24
  • 1
    It worked perfect now I can request properties of my claims – Enrique Dec 21 '20 at 23:02