Search code examples
asp.net-identity-2

Asp.net Identity 2 User.Identity.GetUserId<int>() always returns 0?


I've extended the Asp.net Identity 2 model to use integer keys by following posts like this and this. However, this line of code always returns 0.

User.Identity.GetUserId<int>()

Even when User.Identity.IsAuthenticated is true and User.Identity.GetUserName() returns the proper username. I've seen this post but it does not help as I am already calling User.Identity.GetUserId() inside a controller method and not the constructor. The reference in that post to the "getUserIdCallback" is interesting though and maybe I need something like that wired up. Any help is much appreciated.


Solution

  • It turns out I needed to add the user's id to the ClaimsIdentity in my custom OAuthAuthorizationServerProvider's GrantResourceOwnerCredentials method. Here is the method:

    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin") ?? "*";
    
        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });
    
        var userManager = context.OwinContext.GetUserManager<ApplicationUserManager>();
    
        ApplicationUser user = await userManager.FindAsync(context.UserName, context.Password);
    
        if (user == null)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect.");
            return;
        }
    
        var identity = new ClaimsIdentity(context.Options.AuthenticationType);
        //THIS IS THE IMPORTANT LINE HERE!!!!!
        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()));
        identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
        identity.AddClaim(new Claim("sub", context.UserName));
    
        foreach (var role in userManager.GetRoles(user.Id))
        {
            identity.AddClaim(new Claim(ClaimTypes.Role, role));
        }
    
        var props = new AuthenticationProperties(new Dictionary<string, string>
        {
            { "as:client_id", context.ClientId ?? string.Empty }
        });
    
        var ticket = new AuthenticationTicket(identity, props);
        context.Validated(ticket);
    }