15

I need to get ID of user that made some request. In previous versions of Identity I could do it like this:

User.Identity.GetUserId();

But it seems it isn't available anymore.

There is also something like:

User.GetUserId();

But it always returns null, even if User.Identity.IsAuthenticated in true and User.Identity.Name is set correctly.

What should I use to do it?

EDIT: My authenticaton logic is based on [default Visual Studio 2015 template], I hadn't changed much so far in identity, so if you want to check how is it done, you can simply see it on github link I pasted.

Piotrek
  • 10,919
  • 18
  • 73
  • 136
  • Can you post your authentication logic? GetUserId retrieve the Id from user claims. – Hezye Feb 23 '16 at 13:26
  • @Hazye what exactly do you want? My project is based on default template (https://github.com/MyPCIsBetter/ASP.net-core-rc1-default-Visual-Studio-2015-template/tree/master/src/ASPnet5webtemplate) and I hadn't change much so far, you can take a look there – Piotrek Feb 23 '16 at 13:40
  • I've tested User.GetUserId() using the template you provided and it works fine. Make sure the ClaimsIdentity of the current user contain the nameidentifier claim, since this is how the method above is able to retrieve user id. – Hezye Feb 23 '16 at 14:08
  • @Hazye well, it doesn't. I now realised that the code I'm working on uses token based authentication (for API) which is based on this answer: http://stackoverflow.com/questions/29048122/token-based-authentication-in-asp-net-5-vnext/33217122#33217122. User.GetUserId works well in controllers that use the original/built in authentication, but when I use authentication that I've linked, there is no nameidentifier and no User.GetUserId. It seems like I need to implement it. – Piotrek Feb 27 '16 at 14:00
  • @Hezye Do you know how to set nameidentifier claim to make it finally work? – Piotrek Feb 27 '16 at 14:01
  • Okay I think we are getting somewhere, I've posted an answer to your question in an answer format. Please test it and let me know if it works. – Hezye Feb 28 '16 at 14:01

6 Answers6

20

I think there was a built in extension method for that in previous versions but they removed it. you can implement your own to replace it:

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

namespace cloudscribe.Core.Identity
{
    public static class ClaimsPrincipalExtensions
    {
        public static string GetUserId(this ClaimsPrincipal principal)
        {
            if (principal == null)
            {
                throw new ArgumentNullException(nameof(principal));
            }
            var claim = principal.FindFirst(ClaimTypes.NameIdentifier);
            return claim != null ? claim.Value : null;
        }
    }
}

ClaimType.NameIdentifier should map to userid

Joe Audette
  • 35,330
  • 11
  • 106
  • 99
  • 1
    the GetUserId extension does exist in RC1 but in the [latest code](https://github.com/aspnet/Identity/blob/dev/src/Microsoft.AspNetCore.Identity/PrincipalExtensions.cs) they seem to have removed it. – Joe Audette Feb 23 '16 at 13:26
  • check out my answer. – maxisam Jun 02 '16 at 20:48
11

@Joe Audette

it turns out it has been move to other place.

User.GetUserId => UserManager.GetUserId(User)
User.GetUserName => UserManager.GetUserName(User)
User.IsSignedIn => SignInManager.IsSignedIn(User)

detail on github

maxisam
  • 21,975
  • 9
  • 75
  • 84
  • 1
    yeah this change happened in rc2. to me it seems nicer to make extension methods on ClaimsPrincipal instead of needing to inject UserManager and SignInManager into views such as _LoginPartial.cshtml as they do in the latest project template – Joe Audette Jun 03 '16 at 11:22
  • 1
    @JoeAudette Well, to be honest, I do like your way. – maxisam Jun 03 '16 at 16:00
  • This is the better answer and works when you aren't using the proprietary claims protocol. There are many suggestions here that use the ClaimTypes.NameIdentifier constant, which wont work if you are using OpenID claims. The identifier claim is "sub" in this case, not "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier". – Dan May 07 '20 at 22:43
  • the detail on github is incredibly lacking.. what namespace are these methods in? UserManager has at least two namespaces... – Scuba Steve Oct 06 '22 at 02:04
9

Following our discussion, it seems your user identity does not contain the correct claim used by User.GetUserId().

Here is how you can manually set the NameIdentifier claim:

// ClaimsIdentity identity = new ClaimsIdentity...

identity.AddClaim(ClaimTypes.NameIdentifier, user.Id);
Hezye
  • 1,521
  • 1
  • 13
  • 15
  • Yeah, it seems like it work. Finally. Thanks! But I still don't understand what's really happening here, in this whole Authentication process. How it works and where all this data about currently active users are stored. Do you know some nice sources to read about it? – Piotrek Feb 29 '16 at 17:53
  • it's not part of the SO question, but it seems like you know something about this... maybe you can recommend me something to read – Piotrek Feb 29 '16 at 17:54
  • 1
    Great. The data about users is stored inside the token generated by the authorization server (e.g. User Id) for each user. This token is then passed to the server by the client/user either in the HTTP request header (web api) or by cookie (mvc). The server is then able to verify and decrypt the token to get user information. You can read about claim based identity here: https://msdn.microsoft.com/en-us/library/ee517291.aspx – Hezye Mar 02 '16 at 11:32
1

My goal was to retrieve the UserId in a custom middleware this is what I used:

httpContext.User.Identity.IsAuthenticated ? 
    httpContext.User.Claims.Where(c => c.Type == ClaimTypes.NameIdentifier).First().Value 
    : Guid.Empty.ToString()
Enkode
  • 4,515
  • 4
  • 35
  • 50
-2

User.Identity.GetUserId(); Is available inside a class that inherits Page.

-4

You can also use

User.Identity.Name;

For more information go to MSDN

https://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity(v=vs.110).aspx