如何在 blazor 页面上使用 usermanager?
how to use usermanager on a blazor page?
你好社区我有一个问题如何在 blazor
页面 webassembly 中使用 usermanager
?通过注入:
@inject UserManager<ApplicationUser> UserManager;
我得到的指示是缺少使用指令,因为 class ApplicationUser class 在服务器上,而客户端无法访问服务器。
这是我在 blazor 页面中的代码:
@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.");
}
}
}
这是我的 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; }
}
您不能使用 WebAssembly Blazor 应用中的 UserManager
,因为它在浏览器上是 运行。一般来说,您不能在 WebAssembly Blazor 应用程序中使用与数据库访问相关的对象。相反,您通常创建 Web Api 操作方法,并使用 Fetch API (HttpClient).
访问这些方法
您想从用户对象中提取什么值?
什么是 Nombre
?
无论 Nombre
是什么,您都可以将此值 (Nombre
) 添加为声明并从 authState.User
访问它
更新
首先,您应该创建一个名为 ApplicationUserClaimsPrincipalFactory 的服务 class,用于将 table 列的值从用户 table 转换为添加到 ClaimsPrincipal 对象的声明传递给 Blazor 客户端。
(服务器应用程序)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
将以下内容放在 .AddDBContext 下方:
services.AddScoped<ApplicationUserClaimsPrincipalFactory>();
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddClaimsPrincipalFactory<ApplicationUserClaimsPrincipalFactory>();
services.AddIdentityServer()
.AddApiAuthorization(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();
客户端
运行 这段代码,看看它是否有效...如果不能,请 post 完成错误报告
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();
}
}
你好社区我有一个问题如何在 blazor
页面 webassembly 中使用 usermanager
?通过注入:
@inject UserManager<ApplicationUser> UserManager;
我得到的指示是缺少使用指令,因为 class ApplicationUser class 在服务器上,而客户端无法访问服务器。
这是我在 blazor 页面中的代码:
@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.");
}
}
}
这是我的 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; }
}
您不能使用 WebAssembly Blazor 应用中的 UserManager
,因为它在浏览器上是 运行。一般来说,您不能在 WebAssembly Blazor 应用程序中使用与数据库访问相关的对象。相反,您通常创建 Web Api 操作方法,并使用 Fetch API (HttpClient).
您想从用户对象中提取什么值?
什么是 Nombre
?
无论 Nombre
是什么,您都可以将此值 (Nombre
) 添加为声明并从 authState.User
更新
首先,您应该创建一个名为 ApplicationUserClaimsPrincipalFactory 的服务 class,用于将 table 列的值从用户 table 转换为添加到 ClaimsPrincipal 对象的声明传递给 Blazor 客户端。
(服务器应用程序)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
将以下内容放在 .AddDBContext 下方:
services.AddScoped<ApplicationUserClaimsPrincipalFactory>();
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddClaimsPrincipalFactory<ApplicationUserClaimsPrincipalFactory>();
services.AddIdentityServer()
.AddApiAuthorization
// 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();
客户端
运行 这段代码,看看它是否有效...如果不能,请 post 完成错误报告
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();
}
}