Proper way to get current User ID in Entity Framework Core

后端 未结 4 855
灰色年华
灰色年华 2021-02-07 01:56

There are a bunch of different answers floating around here for the different RC\'s of ASP.NET Core on how to get the ID of the currently logged in user. I wanted to ask the def

相关标签:
4条回答
  • 2021-02-07 02:45

    ASP.NET Core Identity is injected via DI in the startup.cs - as such you just have to inject UserManager via a constructor

    UserManager<ApplicationUser> userManager
    

    You can then use the following in methods

    _userManager.GetUserId(User);
    

    That's the way its used in the Sample Web Application when you create a new ASP.NET Core 1 project with Individual User Account.

    0 讨论(0)
  • 2021-02-07 02:48

    If you are accessing this from withing the Controller, then using UserManager to get the user ID is pretty inefficient as you are making a round trip to the database. If you are using ClaimsIdentity, you can do something like this to get the user id:

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

    This method just reads the user ID which is already present in the cookie, which in turn is automatically deserialized and stored in a ClaimsIdentity instance.

    I use this helper class:

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

    So getting a user ID becomes:

    var userId = this.User.GetUserId();
    

    If, for some reason, the required claim is not present in the Claims colleciton, you can easily add it when creating the user's ClaimsIdentity:

    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;
        }
    }
    
    0 讨论(0)
  • 2021-02-07 02:56

    The one-liner below is a more concise version of the other answers above.

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

    To explain a little further, I wanted to use the most basic form of authentication without any tables in the database so I chose this one - Using Cookie Authentication without ASP.NET Core Identity from the Core documentation.

    To get this working, the first step is to add the services in 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;
    });
    

    Then in the AccountController on the post back having entered a valid user id and password, the simplest Claims based authentication is to just add the login id as a Claim, e.g.

    var claims = new List { new Claim(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
                    });
    

    Once the Sign In completes you can retrieve the user id as described in the one liner above. See the answer from Milos Mrdovic above for the more detailed steps.

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

    See Claims-Based Authorization for further information.

    0 讨论(0)
  • 2021-02-07 02:57

    You can get UserId by this way also.

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

    Where ApplicationUser class is given below....

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

    And Your ApplicationUser class should inherited by IdentityUser.

    0 讨论(0)
提交回复
热议问题