Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net core 在实体框架核心中获取当前用户ID的正确方法_Asp.net Core_Asp.net Identity_Entity Framework Core - Fatal编程技术网

Asp.net core 在实体框架核心中获取当前用户ID的正确方法

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

关于如何获取当前登录用户的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,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; }
    }