Continuing my foray into ASP .NET Core, and making sure I get outside my comfort zone, I got into the situation that I want to be able to easily access the logged in user information in my API request.
There are several versions available online, some unfortunately out of date (mostly because ASP .NET Core 2.0 is relatively new and things changed significantly in Identity between 1.0 and 2.0).
First version I stumbled upon recommended extending the IHttpContextAccessor. In case you don’t know, in C# you can use a custom extension method to implement your own extensions to core libraries.
The code in my nativity looked like:
|
|
Technically, that returns the user.Id since that’s what my Claim definition specified. (ignore the fact that I only have one of the ‘important’ tokens)
|
|
Because of the fact that Microsoft ‘knows’ best (yes all separate links, I promise I’ll make a docs pull request) we need to add System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
in our Startup.cs
/ ConfigureServices
(easiest is to just dump it at the top) in order to avoid the automatic conversion of the sub type to ClaimTypes.NameIdentifier
.
For some reason this is not improved in 2.0 even if it was a good occasion since it broke backwards compatibility (hoping to have this in 2.1 since the recent blog post suggested that 2.1 will not follow SemVer and could introduce breaking changes).
That being changed you can then redefine the UserIdClaimType
to use the Jwt claim.
|
|
To be honest, I understand why this got ignored, because most of the time, your CurrentUser method would most likely look like:
|
|
This works even if you don’t reset the Claim handling since behind the scenes it does the transformation for you into ClaimTypes.NameIdentifier
. I’m not a big fan since even if convention over configuration is nice to have, this is a bit too magical for me since it also does a claim type conversion.
Now, as an alternative you could always just call the GetUserAsync
method on your UserManager
directly inside the controller because you have direct access to HttpContext.User
(or this.User
, again I like it a bit more explicit).
|
|
How are you guys handling this ? Anything that I should keep in mind as best practice ?