question

RonaldRex-2335 avatar image
0 Votes"
RonaldRex-2335 asked AgaveJoe edited

JWT Token Expiration and Authorization

I am working with a JWT in .Net Core 6.0 Web Api. I am struggling with JWT expiration time...not sure if it is being set correctly with the UTC being different from my loacl time. But I also am having an issue with not being able to run an API Method after I Annotate the Method with [Authorize], even though I generate a token and send it with the request in postman. Really odd behavior with the JWT and expiration. Thanks for any help !!!

dotnet-aspnet-core-webapidotnet-entity-framework-coremicrosoft-identity-managerdotnet-aspnet-core-security
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

It's hard to provide assistance without the source code.

0 Votes 0 ·

 //Jwt Authentication
        
                 var key = Encoding.UTF8.GetBytes(Configuration["ApplicationSettings:JWT_Secret"].ToString());
                 services.AddAuthentication(x =>
                 {
                     x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                     x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
                     x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        
                 }).AddJwtBearer(x =>
                 {
                     x.RequireHttpsMetadata = false;
                     x.SaveToken = false;
                     x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                     {
                         ValidateIssuerSigningKey = true,
                         IssuerSigningKey = new SymmetricSecurityKey(key),
                         ValidateIssuer = true,
                         ValidateAudience = true,
                         ValidateLifetime = true,
                         ClockSkew = TimeSpan.Zero
                     };
                 });
0 Votes 0 ·

[HttpPost]
[Route("Login")]
//POST : /api/ApplicationUser/Login

                     var tokenDescriptor = new SecurityTokenDescriptor
                     {
                         Subject = new ClaimsIdentity(new Claim[]
                         {
                             new Claim("UserID", user.Id.ToString()),
                             new Claim(_options.ClaimsIdentity.RoleClaimType, role.FirstOrDefault())
                         }),
        
                         Expires = DateTime.UtcNow.AddMinutes(60),
        
                     //Expires = DateTime.UtcNow.AddMinutes(10),
                         SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.JWT_Secret)), SecurityAlgorithms.HmacSha256Signature)
                     };
                     var tokenHandler = new JwtSecurityTokenHandler();
                     var securityToken = tokenHandler.CreateToken(tokenDescriptor);
                     var token = tokenHandler.WriteToken(securityToken);
                     return Ok(new { token });
                 }
                 else
                     return BadRequest(new { message = "USERNAME or password is Incorrect." });
             }


0 Votes 0 ·
Show more comments
AgaveJoe avatar image
0 Votes"
AgaveJoe answered AgaveJoe edited

I noticed the configuration sets issuer and audience validation but the login action does not set these values.

                      x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
                      {
                          ValidateIssuerSigningKey = true,
                          IssuerSigningKey = new SymmetricSecurityKey(key),
                          ValidateIssuer = true,
                          ValidateAudience = true,
                          ValidateLifetime = true,
                          ClockSkew = TimeSpan.Zero
                      };

Either set the configuration values to false or add the issuer and audience claims to the token.

 public string Authenticate(string username, string password)
 {
     var user = _users.SingleOrDefault(x => x.Username == username && x.Password == password);
    
     // return null if user not found
     if (user == null)
         return null;
    
     // authentication successful so generate jwt token
     var tokenHandler = new JwtSecurityTokenHandler();
     var key = Encoding.ASCII.GetBytes(Configuration["JwtConfig:secret"]);
     var tokenDescriptor = new SecurityTokenDescriptor
     {
         Subject = new ClaimsIdentity(new Claim[]
         {
             new Claim(ClaimTypes.Name, user.Id.ToString()),
         }),
         IssuedAt = DateTime.UtcNow,
         Expires = DateTime.UtcNow.AddMinutes(10),
         SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
         Issuer = "Issuer",
         Audience = "Audience"
     };
     var token = tokenHandler.CreateToken(tokenDescriptor);
     return tokenHandler.WriteToken(token);
 }

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Bruce-SqlWork avatar image
0 Votes"
Bruce-SqlWork answered Bruce-SqlWork edited

typically an access token is good for 60 minutes. does the token have the scope to call the method? it a valid access token or an id token?

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

BrandoZhang-MSFT avatar image
0 Votes"
BrandoZhang-MSFT answered

Hi @RonaldRex-2335,

The expire time for the token is generated when you are using the token generated codes. Since we don't know how you generate that token, if you write the JWT token generation by yourself, I suggest you could try to modify the expires property like below:

             var token = new JwtSecurityToken(configuration["Jwt:Issuer"], configuration["Jwt:Issuer"], 
                             null, expires: DateTime.Now.AddMinutes(60),
                             signingCredentials: credentials); //60mins expiration 

More details, you could refer to JwtSecurityToken Constructors.


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.