ASP.NET Core. JWT. How to revoke a token?

Hi all. Write the application on ASP.NET Core. Did everything like in this article: ASP.NET Core | JWT-tokens.

Created a method to change the password. Now the question is. After changing the password, I need to make the token invalid. Or to update it. How can I do this? Because we need access from all devices.

I don't know much about the JWT. I will be glad to hear your answers.
March 20th 20 at 11:20
1 answer
March 20th 20 at 11:22
1. The token has no password, therefore why update it?
2. The token contains (optional) field jti, which is your unique ID for this token (JWT ID). On the server side can generate a list of such identifiers and to define the actions for the requests that will come with the token has the given ID. The lifetime of the list should be longer than the time validity of the token.
If understand correctly, you need to create a list of tokens? Honestly, I can't deal with this topic. All give different advice.

OK, I've made a list of tokens. Them the database to save? - brandon commented on March 20th 20 at 11:25
@Connie32, Different answers, as there are many options. For example, the list can be stored in memory, on disk in a file, database or somewhere else. - abdullah.Botsford commented on March 20th 20 at 11:28
@penelope.Ki, sorry if I ask stupid questions. But I did not understand how to implement it.

Ie you can save the tokens in a DB. For example, I got a token 2 times, I need to compare with the token from the database?

IMHO, I do not delve into this topic. - brandon commented on March 20th 20 at 11:31
@Connie32, For example you decide that users with the old token should login again. You get the request token, get its ID and check that ID on the presence in the created table in the database. If it is there, the token is valid. - abdullah.Botsford commented on March 20th 20 at 11:34
That's the problem. After changing the password, the token does not change.
[HttpPost("[action]")]
 [Authorize(AuthenticationSchemes = "Bearer")]
 public async Task<IActionResult> ChangePassword([FromBody] ChangePasswordViewModel model)
{
try
{
 var account = await _userManager.FindByNameAsync(User.Identity.Name);
 var user = await _context.Users.FirstOrDefaultAsync(u => u.Id == account.Id);

 if (user != null)
{
 IdentityResult result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
 if (result.Succeeded)
{
 var userName = user.Email;
 var password = model.OldPassword;

 var principial = await LoginNotConfirmedPrincipial(user.Id);
 if (principial == null)
 return StatusCode(400, "Invalide username or password");

 DateTime now = DateTime.UtcNow;

 var jwt = new JwtSecurityToken(
 issuer: AuthOptions.ISSUER,
 audience: AuthOptions.AUDIENCE,
 notBefore: now,
 claims: principial.Claims,
 expires: now.Add(TimeSpan.FromSeconds(AuthOptions.LIFETIME)),
 signingCredentials: SigningCredentials new(AuthOptions.GetSymmetricSecurityKey(), SecurityAlgorithms.HmacSha256));
 var encodeJwt = new JwtSecurityTokenHandler().WriteToken(jwt);

 var principalUser = await _userManager.FindByNameAsync(principial.Name);

 var response = new
{
 token = encodeJwt,
 user = new
{
 isAuthenticated = true,
 name = principalUser.UserName
 roles = await _userManager.GetRolesAsync(principalUser)
}
};

 return Ok(response);
}
else
{
 foreach (var error in result.Errors)
{
 ModelState.AddModelError(string.Empty, error.Description);
}
 return Ok(result.Errors);
}
}
else
{
 return new EmptyResult();
}
}
 catch (Exception e)
{
 return Ok(e.Message);
}
}

private async Task<ClaimsIdentity> LoginNotConfirmedPrincipial(string userId)
{
 Account user = await _userManager.FindByIdAsync(userId);
 if (user != null)
{
 var roles = await _userManager.GetRolesAsync(user);
 var claims = new List<Claim>
{
 new Claim(ClaimsIdentity.DefaultNameClaimType, user.UserName),
 new Claim(ClaimsIdentity.DefaultRoleClaimType, roles[0])
};
 ClaimsIdentity claimsIdentity =
 new ClaimsIdentity(claims, "Token", ClaimsIdentity.DefaultNameClaimType,
ClaimsIdentity.DefaultRoleClaimType);
 return claimsIdentity;
}
 return null;
 }
- brandon commented on March 20th 20 at 11:37
@Connie32, What does not change? Where should he change? You brought a new somewhere, and there will know that got a new one. And all other clients know about it can't. They will send the old, and you have to handle - abdullah.Botsford commented on March 20th 20 at 11:40
@penelope.Ki, I mean, I don't know how to handle. - brandon commented on March 20th 20 at 11:43

Find more questions by tags JSON Web Token