Asp.net core 在实体框架核心中获取当前用户ID的正确方法
关于如何获取当前登录用户的ID,ASP.NET核心的不同RC有很多不同的答案。我想在这里问一个明确的问题。请注意,project.json现在有“Microsoft.AspNetCore.Identity.EntityFrameworkCore”:“1.0.0” 使用RC1,您可以执行以下操作:Asp.net core 在实体框架核心中获取当前用户ID的正确方法,asp.net-core,asp.net-identity,entity-framework-core,Asp.net Core,Asp.net Identity,Entity Framework Core,关于如何获取当前登录用户的ID,ASP.NET核心的不同RC有很多不同的答案。我想在这里问一个明确的问题。请注意,project.json现在有“Microsoft.AspNetCore.Identity.EntityFrameworkCore”:“1.0.0” 使用RC1,您可以执行以下操作: using Microsoft.AspNet.Identity; using System.Security.Claims; User.GetUserId(); 但对于最新发布的EF Core版本1
using Microsoft.AspNet.Identity;
using System.Security.Claims;
User.GetUserId();
但对于最新发布的EF Core版本1,Microsoft.AspNet.Identity不是正确的版本
有人建议使用UserManager,这似乎只是为了获得当前登录的用户:
private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);
var user = await GetCurrentUserAsync();
var userId = user?.Id;
如果您是通过控制器访问它的,那么使用UserManager获取用户ID是非常低效的,因为您要往返数据库。如果您使用的是ClaimSideEntity,则可以执行以下操作以获取用户id:
var claimsIdentity = (ClaimsIdentity)this.User.Identity;
var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
var userId = claim.Value;
此方法只读取cookie中已经存在的用户ID,然后自动反序列化并存储在ClaimSideEntity实例中
我使用这个助手类:
public static class UserHelpers
{
public static string GetUserId(this IPrincipal principal)
{
var claimsIdentity = (ClaimsIdentity)principal.Identity;
var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
return claim.Value;
}
}
因此,获取用户ID变成:
var userId = this.User.GetUserId();
如果由于某种原因,索赔集合中不存在所需索赔,您可以在创建用户索赔实体时轻松添加该索赔:
公共类应用程序用户:IdentityUser
{
公共异步任务GenerateUserIdentityAsync(用户管理器)
{
var userIdentity=wait manager.CreateIdentityAsync(这是DefaultAuthenticationTypes.ApplicationOkie);
AddClaim(新声明(ClaimTypes.NameIdentifier,this.UserId));
返回用户身份;
}
}
ASP.NET核心标识是通过startup.cs中的DI注入的-因此,您只需通过构造函数注入UserManager即可
UserManager<ApplicationUser> userManager
当您使用个人用户帐户创建新的ASP.NET Core 1项目时,示例Web应用程序中就是这样使用的。下面的一行是上面其他答案的更简洁版本
var user = User.FindFirst(ClaimTypes.NameIdentifier).Value;
为了进一步解释,我想使用最基本的身份验证形式,而数据库中没有任何表,所以我选择了这个-
从核心文档中
要使其正常工作,第一步是在Startup.cs中添加服务
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = new PathString("/Account/Login/");
options.LogoutPath = new PathString("/Account/Logoff/");
options.AccessDeniedPath = new PathString("/Account/AccessDenied/");
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
services.ConfigureApplicationCookie(identityOptionsCookies =>
{
// See https://andrewlock.net/automatically-validating-anti-forgery-tokens-in-asp-net-core-with-the-autovalidateantiforgerytokenattribute/
identityOptionsCookies.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
然后,在帖子背面的AccountController中,输入有效的用户id和密码后,最简单的基于声明的身份验证就是将登录id添加为声明,例如
var索赔=新列表
{
新声明(ClaimTypes.NameIdentifier、loginViewModel.Guid、ClaimValueTypes.String、issuer),
};
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(claimsIdentity);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal,
new AuthenticationProperties
{
ExpiresUtc = DateTime.UtcNow.AddMinutes(_cookieTimeoutInMinutes),
IsPersistent = true,
AllowRefresh = false
});
登录完成后,您可以按照上面的一行代码中所述检索用户id。有关更详细的步骤,请参见上面Milos Mrdovic的答案
var user = User.FindFirst(ClaimTypes.NameIdentifier).Value;
有关更多信息,请参阅。您也可以通过这种方式获取用户ID
public class Program
{
private readonly SignInManager<ApplicationUser> _signInManager;
public Program(SignInManager<ApplicationUser> signInManager)
{
_signInManager = signInManager;
var UserId = _signInManager.Context.User.Claims.FirstOrDefault().Value;
}
}
您的ApplicationUser类应该由IdentityUser继承。请不要对标签标题提出疑问!我很惊讶没有内置的方法来获取当前登录的用户ID。此方法与旧Users.Identity.GetUserId()的工作方式或行为方式是否有任何不同?此方法使用与旧GetUserId相同的基本逻辑。区别在于,您可以直接在用户对象上调用它,而不是在User.Idenity对象上调用它。检查此答案以进行比较。我相信他们删除它的原因是因为强制转换为ClaimSidenty违反了LSP。将此用于framework 4.5.2上的asp.net核心应用程序。添加nuget软件包Microsoft.AspNet.Identity导致了与现有框架引用的歧义和冲突。在2020年(ASP.NET Core 3.1),人们仍在尝试解决同样的问题!看起来这仍然是最好的答案。为什么他们不向
User.Identity
添加“Id”属性是个谜。Done@PetterFriberg:)。
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
{
options.LoginPath = new PathString("/Account/Login/");
options.LogoutPath = new PathString("/Account/Logoff/");
options.AccessDeniedPath = new PathString("/Account/AccessDenied/");
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
services.ConfigureApplicationCookie(identityOptionsCookies =>
{
// See https://andrewlock.net/automatically-validating-anti-forgery-tokens-in-asp-net-core-with-the-autovalidateantiforgerytokenattribute/
identityOptionsCookies.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
var principal = new ClaimsPrincipal(claimsIdentity);
await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal,
new AuthenticationProperties
{
ExpiresUtc = DateTime.UtcNow.AddMinutes(_cookieTimeoutInMinutes),
IsPersistent = true,
AllowRefresh = false
});
var user = User.FindFirst(ClaimTypes.NameIdentifier).Value;
public class Program
{
private readonly SignInManager<ApplicationUser> _signInManager;
public Program(SignInManager<ApplicationUser> signInManager)
{
_signInManager = signInManager;
var UserId = _signInManager.Context.User.Claims.FirstOrDefault().Value;
}
}
public class ApplicationUser:IdentityUser
{
[Column(TypeName = "Nvarchar(500)")]
public string FirstName { get; set; }
[Column(TypeName = "Nvarchar(500)")]
public string MiddleName { get; set; }
[Column(TypeName = "Nvarchar(500)")]
public string LastName { get; set; }
[Column(TypeName = "DateTime")]
public DateTime? LastAccess { get; set; }
}