[英]Why does UserManager.GetUserAsync return null when using JWT?
[英]why does UserManager.GetUserAsync not return?
为什么 UserManager.GetUserAsync 不返回?
当我在关于页面上手动单击时,将在 blazor UI 中访问属性 IsAdmin。 我不明白为什么对 GetUSerAsync 的调用没有返回。 有什么线索或错误吗? 为简单起见,我删除了锁定代码。 (没有也不起作用)
关于.razor.cs
using System.Collections.Generic;
using System.Linq;
using Common.Server.Logic.Services;
using Common.Shared.Extensions;
using Microsoft.AspNetCore.Components;
namespace Common.Server.UI.Pages
{
public partial class About : ComponentBase
{
#nullable disable
[Inject]
private UserSessionInfo UserSession { get; set; }
private string IsAdminText { get; set; }
private IEnumerable<string> UserRoleNames { get; set; } = Enumerable.Empty<string>();
#nullable restore
protected override void OnInitialized()
{
IsAdminText = UserSession.IsAdmin.Format();
UserRoleNames = UserSession.UserRoles;
}
}
}
用户会话信息.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using AspNetCore.ServiceRegistration.Dynamic.Interfaces;
using Common.Server.Logic.Bases;
using Common.Shared;
using Common.Shared.Extensions;
using Common.Shared.Models.Logging.Bases;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
namespace Common.Server.Logic.Services
{
public class UserSessionInfo : LockingBase, IHasUsername, IScopedService
{
public DateTime LoginAt { get; set; }
private UserManager<IdentityUser> UserManager { get; }
private AuthenticationStateProvider AuthenticationStateProvider { get; }
public IEnumerable<string> UserRoles { get; private set; } = Enumerable.Empty<string>();
private string? _username;
public string? Username
{
get
{
CheckInitialized();
return _username;
}
}
private bool _isAdmin;
public bool IsAdmin
{
get
{
CheckInitialized();
return _isAdmin;
}
}
public UserSessionInfo(IServiceProvider serviceProvider)
{
UserManager = serviceProvider.GetRequiredService<UserManager<IdentityUser>>();
AuthenticationStateProvider = serviceProvider.GetRequiredService<AuthenticationStateProvider>();
}
private void CheckInitialized()
{
if (_username is null)
// double lock
SyncLock.Lock(async () => await InitializeAsync()).GetAwaiter().GetResult();
}
private async Task InitializeAsync()
{
var claimsPrincipal = (await AuthenticationStateProvider.GetAuthenticationStateAsync()).User;
var user = await UserManager.GetUserAsync(claimsPrincipal); // Does not return
_isAdmin = await UserManager.IsInRoleAsync(user, Const.Authorization.Roles.AdminRoleName);
UserRoles = await UserManager.GetRolesAsync(user);
var username = await UserManager.GetUserNameAsync(user);
Interlocked.Exchange(ref _username, username);
}
}
}
也(startup.cs):
services.AddDefaultIdentity<IdentityUser>()
.AddRoles<IdentityRole>()
.AddClaimsPrincipalFactory<UserClaimsPrincipalFactory<IdentityUser, IdentityRole>>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders()
.AddDefaultUI();
services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
services.AddScoped<UserSessionInfo>();
当异步方法没有返回时, .GetAwaiter().GetResult()
是第一个嫌疑人。
很可能您的调用代码(渲染器?)正在让您的 Username 和 IsAdmin 属性重叠,然后您就会出现死锁。 但是如果没有看到整个调用链,我们就无法确定。
根据经验,您不需要锁定或 GetResult(或 .Wait()、.Result)。 当你认为你这样做时,可能是时候备份了。
最后我找到了解决方案。 (以及它不起作用的原因)
问题是我在 OnInitialized 回调期间访问了 IsAdmin 而不是 OnInitializedAsync。
将 IsAdmin 的访问权限放入 OnInitializedAsync 一切正常!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.