Proper way to get current User ID in Entity Framework Core

asp.net-core asp.net-identity entity-framework-core

Question

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 definite question here. Please note that project.json now has "Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0"

With RC1, you could do something like this:

using Microsoft.AspNet.Identity;
using System.Security.Claims;

User.GetUserId();

But with the newly released version 1 of EF Core, Microsoft.AspNet.Identity is not the right version.

There was suggestions to use UserManager, which seems like a lot just to get the currently logged in user:

private Task<ApplicationUser> GetCurrentUserAsync() => _userManager.GetUserAsync(HttpContext.User);

var user = await GetCurrentUserAsync();
var userId = user?.Id;

Another method that I found was:

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

So with ASP.NET Core 1 RTM and EF Core 1 with the following libraries in project.json, what is the proper way to get the id of the currently logged in user?

"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0",
"Microsoft.AspNetCore.Mvc": "1.0.0",
1
19
7/23/2016 3:31:35 PM

Accepted Answer

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.

15
7/26/2016 4:54:19 PM

Popular Answer

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


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow