在AuthController
进行身份验证时,我会创建一些声明-UserID
是其中之一。
...
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim("UserID", user.Id.ToString()),
})
当Angular应用发出请求时,我可以在另一个 Controller 中获取
UserID
Claim claimUserId = User.Claims.SingleOrDefault(c => c.Type == "UserID");
ControllerBase.User
实例包含.Identity
对象,该对象又包含Claims
集合。Identity.IsAuthenticated
等于True
。 Identity.Name
保留admin
字符串(相关用户的名称)。 如果我尝试这样获取用户:
var user = await UserManager.GetUserAsync(HttpContext.User)
user
是null
。也许,我忘了增加一些额外的要求?
或者,也许,一旦我使用了JWT,我应该覆盖默认的
UserManager
功能,以便它通过保存claim
的UserID
来获取用户?还是有更好的方法?
附加信息:
Identity
注册如下services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
ApplicationUser.Id
字段的类型为bigint
(或在C#中为long
)另外,我使用UserManager以
EF Seed Data
创建用户,使用ServiceProvider
解决了该问题_userManager = scope.ServiceProvider.GetService<UserManager<ApplicationUser>>();
...
adminUser.PasswordHash = new PasswordHasher<ApplicationUser>().HashPassword(adminUser, "123qwe");
_userManager.CreateAsync(adminUser);
最佳答案
UserManager.GetUserAsync
在内部使用 UserManager.GetUserId
检索用户的用户ID,然后将其用于从用户存储区(即您的数据库)查询对象。GetUserId
基本上如下所示:
public string GetUserId(ClaimsPrincipal principal)
{
return principal.FindFirstValue(Options.ClaimsIdentity.UserIdClaimType);
}
因此,这将返回Options.ClaimsIdentity.UserIdClaimType
的声明值。 Options
是用来配置Identity的 IdentityOptions
object。默认情况下,UserIdClaimType
的值为ClaimTypes.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()),
})
或者您正确配置了身份,以便它将使用您的UserID
声明类型:// in Startup.ConfigureServices
services.AddIdentity(options => {
options.ClaimsIdentity.UserIdClaimType = "UserID";
});