Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Claim NameIdentifier Id gets convert error

i have problem with this code:

private async Task<object> GenerateJwtToken(string email, User user)
{
    var claims = new List<Claim>
    {
        new Claim(JwtRegisteredClaimNames.Sub, email),
        new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
        new Claim(ClaimTypes.NameIdentifier, user.Id)
    };

User extend IdentityUser. The problem is that i get :

Cannot convert from 'int' to 'System.Security.Claims.ClaimsIdentity'". Even for ClaimTypes.NameIdentifier i get error: "Cannot convert from 'string' to 'System.IO.BinaryReader'

And if i change Id to something else, like email, or firstName errors disappear... Can't find any info about it.

like image 758
Šarūnas Reklaitis Avatar asked May 29 '18 15:05

Šarūnas Reklaitis


People also ask

What is ClaimTypes NameIdentifier?

ClaimTypes.Name is for username and ClaimTypes. NameIdentifier specifies identity of the user as object perspective.

What is claims identity C#?

ClaimsIdentity(IIdentity) Initializes a new instance of the ClaimsIdentity class using the name and authentication type from the specified IIdentity. ClaimsIdentity(IIdentity, IEnumerable<Claim>) Initializes a new instance of the ClaimsIdentity class using the specified claims and the specified IIdentity.

Where are user claims stored?

By default, a user's claims are stored in the authentication cookie. If the authentication cookie is too large, it can cause the app to fail because: The browser detects that the cookie header is too long.


2 Answers

Understandably I am a bit late to this question but I had a similar issue.

What I found was new Claim has multiple signatures that can be passed into it. Explicitly stating the type resolved my issue.

new Claim(ClaimTypes.Name as string, userFromRepo.Username as string)

Hopefully this gives some help to anyone else who has this issue.

like image 56
Martyn93 Avatar answered Sep 17 '22 12:09

Martyn93


Normally how it works (at least in ASP.NET Core 3) is that the sub JWT claim gets automatically converted (by the InboundClaimTypeMap) into NameIdentifier when the scaffolding instantiates the ClaimsPrincipal.

So it's enough to simply set a JwtRegisteredClaimNames.Sub claim with user.Id as value.

But you can customize which claim the Identity should use for identification purposes by assigning a value to IdentityOptions.ClaimsIdentity.UserIdClaimType in the AddIdentity() call, e.g.:

services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
   options.ClaimsIdentity.UserIdClaimType = JwtRegisteredClaimNames.Sub;
});

And if you want to disable the claim mapping, you can clear the map by including the following statement in the configuration:

JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();

or set this flag to false:

JwtSecurityTokenHandler.DefaultMapInboundClaims = false;
like image 38
Leaky Avatar answered Sep 20 '22 12:09

Leaky