how to use usermanager on a blazor page?

五迷三道 提交于 2021-02-11 07:01:29

问题


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; }
        }


回答1:


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();
    }
}


来源:https://stackoverflow.com/questions/65397419/how-to-use-usermanager-on-a-blazor-page

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!