JWT身份验证 - UserManager.GetUserAsync返回null

Ale*_*man 11 c# claims-based-identity asp.net-identity asp.net-core

AuthController身份验证时,我创建了几个声明 - UserID就是其中之一.

...
Subject = new ClaimsIdentity(new[]
{
  new Claim(ClaimTypes.Name, user.UserName),
  new Claim("UserID", user.Id.ToString()),
})
Run Code Online (Sandbox Code Playgroud)

当Angular应用程序发出请求时,我可以UserID在另一个控制器中获取

Claim claimUserId = User.Claims.SingleOrDefault(c => c.Type == "UserID");
Run Code Online (Sandbox Code Playgroud)

ControllerBase.User实例包含.Identity对象则持有Claims集合.

  • Identity.IsAuthenticated等于True.

  • Identity.Name保存admin字符串(相关用户的名称).

如果我尝试像这样获取用户:

var user = await UserManager.GetUserAsync(HttpContext.User)
Run Code Online (Sandbox Code Playgroud)

usernull.

也许,我忘了添加一些额外的索赔?

或者,也许,一旦我使用JWT - 我应该覆盖默认UserManager功能,以便它获取用户claim保持UserID

或者可能有更好的方法?


附加信息:

Identity注册如下

services.AddIdentity<ApplicationUser, ApplicationRole>()
    .AddEntityFrameworkStores<AppDbContext>()
    .AddDefaultTokenProviders();
Run Code Online (Sandbox Code Playgroud)

ApplicationUser.Id字段是bigint(或在C#中long)类型

此外,我EF Seed Data使用UserManager 创建用户ServiceProvider

_userManager = scope.ServiceProvider.GetService<UserManager<ApplicationUser>>();
    ...
        adminUser.PasswordHash = new PasswordHasher<ApplicationUser>().HashPassword(adminUser, "123qwe");
        _userManager.CreateAsync(adminUser);
Run Code Online (Sandbox Code Playgroud)

pok*_*oke 24

UserManager.GetUserAsync内部用于UserManager.GetUserId检索用户的用户ID,然后用于从用户存储(即您的数据库)查询对象.

GetUserId 基本上看起来像这样:

public string GetUserId(ClaimsPrincipal principal)
{
    return principal.FindFirstValue(Options.ClaimsIdentity.UserIdClaimType);
}
Run Code Online (Sandbox Code Playgroud)

所以这会返回索赔值Options.ClaimsIdentity.UserIdClaimType.Options是您配置标识的IdentityOptions对象.默认情况下的数值UserIdClaimTypeClaimTypes.NameIdentifier,即"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier".

因此,当您尝试使用UserManager.GetUserAsync(HttpContext.User)该用户主体UserID声明的用户时,用户管理员只是在寻找不同的声明.

你可以通过切换到ClaimTypes.NameIdentifier:

new ClaimsIdentity(new[]
{
    new Claim(ClaimTypes.Name, user.UserName),
    new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
})
Run Code Online (Sandbox Code Playgroud)

或者您正确配置身份,以便它将使用您的UserID声明类型:

// in Startup.ConfigureServices
services.AddIdentity(options => {
    options.ClaimIdentity.UserIdClaimType = "UserID";
});
Run Code Online (Sandbox Code Playgroud)