This is a quick example of how to create and validate JWT tokens in ASP.NET Core 3.1 using the JwtSecurityTokenHandler
class which is part of the System.IdentityModel.Tokens.Jwt
NuGet package. We also cover how to implement custom JWT authentication with custom JWT middleware and a custom authorize attribute.
The code samples use the jwt token handler and a few related classes to create and validate JWT tokens, no other parts of the ASP.NET Core Identity system are used.
.NET Core CLI: dotnet add package System.IdentityModel.Tokens.Jwt
Visual Studio Package Manager Console: System.IdentityModel.Tokens.Jwt
This code generates a JWT token with the specified accountId
as the "id"
claim, meaning the token payload will contain the property "id": <accountId>
(e.g. "id": 123
).
public string GenerateJwtToken(int accountId)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes("[SECRET USED TO SIGN AND VERIFY JWT TOKENS, IT CAN BE ANY STRING]");
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new[] { new Claim("id", accountId.ToString()) }),
Expires = DateTime.UtcNow.AddDays(7),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
This code attempts to validate the provided JWT token
and return the accountId
from the token claims. If validation fails null
is returned.
public int? ValidateJwtToken(string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes("[SECRET USED TO SIGN AND VERIFY JWT TOKENS, IT CAN BE ANY STRING]");
try
{
tokenHandler.ValidateToken(token, new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false,
// set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later)
ClockSkew = TimeSpan.Zero
}, out SecurityToken validatedToken);
var jwtToken = (JwtSecurityToken)validatedToken;
var accountId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value);
// return account id from JWT token if validation successful
return accountId;
}
catch
{
// return null if validation fails
return null;
}
}
Below is custom JWT middleware that validates the JWT token in the request "Authorization"
header if it exists.
On successful JWT validation the middleware retrieves the associated account
from the database and assigns it to context.Items["Account"]
which makes the current account available to any other code running within the current request scope, which we’ll use below in a custom authorize attribute.
#aspdotnet #jwt #security #developer