在Entity Framework Core中获取当前用户ID的正确方法

时间:2016-07-23 15:05:10

标签: asp.net-core asp.net-identity entity-framework-core

对于不同的关于如何获取当前登录用户ID的ASP.NET Core的不同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;

我找到的另一种方法是:

private readonly UserManager<ApplicationUser> _userManager;
_userManager.GetUserId(User)

使用ASP.NET Core 1 RTM和EF Core 1以及project.json中的以下库,获取当前登录用户的id的正确方法是什么?

"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0",

4 个答案:

答案 0 :(得分:21)

如果您使用Controller访问此项,那么使用 UserManager 获取用户ID的效率非常低,因为您要往返数据库。如果您使用的是 ClaimsIdentity ,则可以执行以下操作来获取用户ID:

var claimsIdentity = (ClaimsIdentity)this.User.Identity;
var claim = claimsIdentity.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
var userId = claim.Value;

此方法只读取cookie中已存在的用户ID,该ID又自动反序列化并存储在 ClaimsIdentity 实例中。

我使用这个助手类:

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();

如果出于某种原因, Claims 收集中不存在所需的声明,则可以在创建用户的 ClaimsIdentity 时轻松添加该声明:< / p>

public class ApplicaionUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        userIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, this.UserId));
        return userIdentity;
    }
}

答案 1 :(得分:14)

ASP.NET核心标识在startup.cs中通过DI注入 - 因此您只需通过构造函数注入Us​​erManager

UserManager<ApplicationUser> userManager

然后,您可以在方法中使用以下内容

_userManager.GetUserId(User);

当您使用个人用户帐户创建新的ASP.NET Core 1项目时,这就是它在示例Web应用程序中的使用方式。

答案 2 :(得分:2)

下面的单行内容是上述其他答案的更简洁版本。

var user = User.FindFirst(ClaimTypes.NameIdentifier).Value;

为了进一步解释,我想在数据库中没有任何表的情况下使用最基本的身份验证形式,所以我选择了这个 - 来自Core文档的Using Cookie Authentication without ASP.NET Core Identity

要使其正常工作,第一步是在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 claims = new List                 {                     新索赔(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;

有关详细信息,请参阅Claims-Based Authorization

答案 3 :(得分:0)

您也可以通过这种方式获取UserId。

public class Program
   {
           private readonly SignInManager<ApplicationUser> _signInManager;

           public Program(SignInManager<ApplicationUser> signInManager)
           {
               _signInManager = signInManager;
              var UserId = _signInManager.Context.User.Claims.FirstOrDefault().Value;
           }
   }

下面提供了ApplicationUser类。...

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; }
    }

您的ApplicationUser类应该由IdentityUser继承。