问题
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