9

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.

Selim Yildiz
  • 5,254
  • 6
  • 18
  • 28

5 Answers5

8

I have this error on Visual Code at new Claim(ClaimTypes.Name, userFromRepo.Username), telling Argument 1: cannot convert from 'string' to 'System.IO.BinaryReader'. My code was like this:

    public async Task<IActionResult> ReadUser([FromBody]UserDto userDto){

        User userFromRepo = _authRepository.GetUserAsync();
        //generate token for user
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes("my secret key");
        var tokenDescriptor = new SecurityTokenDescriptor{
            Subject = new ClaimsIdentity(new Claim[]
            {
                new Claim(ClaimTypes.NameIdentifier, userFromRepo.Id.ToString()),
                new Claim(ClaimTypes.Name, userFromRepo.Username) //error here in this ctor

            }),
            Expires = DateTime.Now.AddDays(1),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature)
        };

After adding await keyword missing before my repository method, which is async by the way, the error is now gone.

    public async Task<IActionResult> ReadUser([FromBody]UserDto userDto){

        User userFromRepo = await _authRepository.GetUserAsync(); //added await
        //generate token for user
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = Encoding.ASCII.GetBytes("my secret key");
        var tokenDescriptor = new SecurityTokenDescriptor{
            Subject = new ClaimsIdentity(new Claim[]
            {
                new Claim(ClaimTypes.NameIdentifier, userFromRepo.Id.ToString()),
                new Claim(ClaimTypes.Name, userFromRepo.Username) //error gets fixed

            }),
            Expires = DateTime.Now.AddDays(1),
            SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature)
        };

Maybe you were facing something similar to this?

Junior Mayhé
  • 16,144
  • 26
  • 115
  • 161
6

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.

Martyn93
  • 338
  • 4
  • 9
3

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;
Leaky
  • 3,088
  • 2
  • 26
  • 35
0

In my case i had a build error on my method signature. After fixing it the error fixed

My method signature is like this:

private async Task<User> AuthenticateUserAsync(string email, string password)

After defining "User" class build error related to method signature is fixed.

Ozan BAYRAM
  • 2,780
  • 1
  • 28
  • 35
0

Convert user.Id to a string

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.ToString())
    };
Denver Naidoo
  • 142
  • 12