在AuthController
中,进行身份验证时,我创建了一些索赔-UserID
是其中之一。
...
Subject = new ClaimsIdentity(new[]
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim("UserID", user.Id.ToString()),
})
当Angular应用发出请求时,我可以在另一个控制器中获取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
的{{1}}获取用户?
或者也许有更好的方法?
其他信息:
UserID
的注册方式如下
Identity
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
字段的类型为ApplicationUser.Id
(或在C#中为bigint
)
此外,我使用long
解析的UserManager在EF Seed Data
中创建用户
ServiceProvider
答案 0 :(得分:20)
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.ClaimIdentity.UserIdClaimType = "UserID";
});