how can I get Identity UserID in the controller right after a successful login result?

18,368

Solution 1

To get claims data and other information about the signed in identity immediately upon a successful login, without going to the database, just access signinManager.AuthenticationManager.AuthenticationResponseGrant.Identity.

For instance,

switch (result) { case SignInStatus.Success: var userId = signinManager.AuthenticationManager.AuthenticationResponseGrant .Identity.GetUserId(); // ...

You can also see it being used in this other question's answer to add new claims to an identity immediately after login - AuthenticationManager.AuthenticationResponseGrant.Identity.AddClaims(freshClaims);

Solution 2

I use System.Security.Claims.ClaimTypes.NameIdentifier object to keep my user id

And I created a helper class to reach the values in it

public class UserHelper
  {
    public static string GetUserId()
    {
      var identity = (System.Security.Claims.ClaimsPrincipal)System.Threading.Thread.CurrentPrincipal;
      var principal = System.Threading.Thread.CurrentPrincipal as System.Security.Claims.ClaimsPrincipal;
      var userId = identity.Claims.Where(c => c.Type == System.Security.Claims.ClaimTypes.NameIdentifier).Select(c => c.Value).SingleOrDefault();
      return userId;
    }
    public static string GetUserName()
    {
      var identity = (System.Security.Claims.ClaimsPrincipal)System.Threading.Thread.CurrentPrincipal;
      var principal = System.Threading.Thread.CurrentPrincipal as System.Security.Claims.ClaimsPrincipal;
      var name = identity.Claims.Where(c => c.Type == System.Security.Claims.ClaimTypes.Name).Select(c => c.Value).SingleOrDefault();
      return name;
    }
    public static string GetUserMail()
    {
      var identity = (System.Security.Claims.ClaimsPrincipal)System.Threading.Thread.CurrentPrincipal;
      var principal = System.Threading.Thread.CurrentPrincipal as System.Security.Claims.ClaimsPrincipal;
      var mail = identity.Claims.Where(c => c.Type == System.Security.Claims.ClaimTypes.Email).Select(c => c.Value).SingleOrDefault();
      return mail;
    }
  }

and I call it with

var user = UserHelper.GetUserId();

Solution 3

you can use below code.

Add function to ApplicationSignInManager class in Identity.Config.cs

 public override Task SignInAsync(ApplicationUser user, bool isPersistent, bool rememberBrowser)
 {
            var claims = new List<Claim>()
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id),
                new Claim(ClaimTypes.Email, user.Email)
            };
            this.AuthenticationManager.User.AddIdentity(new ClaimsIdentity(claims));
            return base.SignInAsync(user, isPersistent, rememberBrowser);
}

Try ths code

private ClaimsPrincipal GetCurrentUser()
        {
            var context = HttpContext.GetOwinContext();
            if (context == null)
                return null;

            if (context.Authentication == null || context.Authentication.User == null)
                return null;

            return context.Authentication.User;
        }
        private string GetUserId()
        {
            var user = GetCurrentUser();
            if (user == null)
                return null;

            var claim = user.Claims.FirstOrDefault(o => o.Type == ClaimTypes.NameIdentifier);
            if (claim == null)
                return null;

            return claim.Value;
        }

        private string GetUserEmail()
        {
            var user = GetCurrentUser();
            if (user == null)
                return null;

            var claim = user.Claims.FirstOrDefault(o => o.Type == ClaimTypes.Email);
            if (claim == null)
                return null;

            return claim.Value;
        }

Solution 4

OK, I found one way; I can get it via:

var userID = UserManager.FindByEmail(loginInfo.Email).Id;

But, I don't think this is the best solution since it seems like I hit the DB with two queries. Can Anyone offer a better solution?

Share:
18,368
A. Burak Erbora
Author by

A. Burak Erbora

Full time developer by day. Game Developer by night. Philosopher in between.

Updated on June 06, 2022

Comments

  • A. Burak Erbora
    A. Burak Erbora almost 2 years

    I am using Identity v2 and MVC 5 for external login.

    In my external login callback function, I log the user in with

    var result = await SignInManager.ExternalSignInAsync(loginInfo, isPersistent: false);
    

    then there is a switch for the result, and I need to access the user's ID in the success case, but User.Identity.GetUserId(); gives me null here.

    How can I access the User's ID in this case?