Home > database >  How does the Jwt tokens work and Errorcode IDX12709
How does the Jwt tokens work and Errorcode IDX12709

Time:01-28

I implemented a Github project and don't understand how the user and the key system for Jwt work. I now have a secret-key which is located in the AppSettings and when the user logs in, the following function is executed:

private string GenerateJwtToken(string username)
{
   var tokenHandler = new JwtSecurityTokenHandler();
   var key = Encoding.ASCII.GetBytes(_appSettings.token);
   var tokenDescriptor = new SecurityTokenDescriptor
   {
      Subject = new ClaimsIdentity(new[] { new Claim("username", username) }), //<-
      Expires = DateTime.UtcNow.AddMinutes(30),
      SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
   };
   var token = tokenHandler.CreateToken(tokenDescriptor);
   return tokenHandler.WriteToken(token);
}

So if I get it right then I generate here the token for the logged in user but what does the line with the username mean? After that I store the username and the token inside the sessionStorage and if I trigger some other Controller where the [Authorize] attribute is defined, I add followed Header with the fetch:

headers: {
   'Content-type': 'application/json',
   'Authorization': `Bearer ${sessionStorage.getItem("token")}`,
},

Then it first run into this functions:

public async Task Invoke(HttpContext context, IAuthService authService)
{
   var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
   if (token != null)
      attachUserToContext(context, authService, token);
   await _next(context);
}

private void attachUserToContext(HttpContext context, IAuthService authService, string token)
{
   try
   {
      var tokenHandler = new JwtSecurityTokenHandler();
      var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
      tokenHandler.ValidateToken(token, new TokenValidationParameters //<- Error
      {
         ValidateIssuerSigningKey = true,
         IssuerSigningKey = new SymmetricSecurityKey(key),
         ValidateIssuer = false,
         ValidateAudience = false,
         ClockSkew = TimeSpan.Zero
      }, out SecurityToken validatedToken);
      var jwtToken = (JwtSecurityToken)validatedToken;
      var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "username").Value);
      context.Items["User"] = "user";
   }
   catch
   {
      // do nothing if jwt validation fails
      // user is not attached to context so request won't have access to secure routes
   }
}

So here it validates that the token from the Header is not null and then it tries to do what!? Also why is again the username used here?

When it run the ValidateToken function it return a error: IDX12709: CanReadToken() returned false. JWT is not well formed: '[PII of type 'System.String' is hidden

https://github.com/cornflourblue/dotnet-5-jwt-authentication-api/tree/279c8058669bbfa59902a4473f62e5371167340c

CodePudding user response:

JWT is split into three parts. The first one is a header with information like encrypting algorithm. The second part is the payload, where you actually can find your claims, in your case, it's gonna be a username, exp date, you can add here whatever you need. Unique username or id is added here for the server to know to who this token belongs and who is calling the server. In other case how would you figure out who is calling the server, you would have to save this token in some database or somewhere with the assigned user. The last part is the signature, this part is verified with your secret key to knowing that it's not some fake token, but actually, a token created by you. Parts are split by dots.

Hard to say why your token validation fails, at first I would try checking your created token on https://jwt.io and see what's inside. Maybe you validate token with bearer prefix, as it's written that token is formed badly, so it can be the issue.

One more thing instead of using custom middleware auth, you can use the JWT default authentication scheme

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = false,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII
                        .GetBytes(Configuration.GetSection("AppSettings:Token").Value)),
                    //...
                };
            });
  •  Tags:  
  • Related