Since there are some changes in JWT for .NET 7 over the previous versions. I have a requirement to generate and validate JWT tokens in my .NET 7 API project. This is done to secure the API access from my WinForms application from where I am accessing the APIs through HTTP Client.
My Program file contains:
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
policy =>
{
policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
});
builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();
My appsettings.json contains
"Authentication": {
"Schemes": {
"Bearer": {
"ValidAudiences": [
"http://localhost:1851",
"https://localhost:44328",
"http://localhost:5078",
"https://localhost:7134"
],
"ValidIssuer": "dotnet-user-jwts",
}
}
},
Above settings was generated in my appsettings.development.json file when I run dotnet user-jwts
command in my project folder.
My problem is above command generate a local token for development and is working fine. But I need to know how to generate JWT token dynamically though the code in C# and also use it in production?
I have tried following code in my API project:
var claims = new List<Claim>
{
new Claim("Name", user.UserName),
};
var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_securityKey));
var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
var tokeOptions = new JwtSecurityToken(
issuer: _config["Authentication:Schemes:Bearer:ValidIssuer"],
audience: _config["Authentication:Schemes:Bearer:ValidAudiences:0"],
claims: claims,
expires: DateTime.Now.AddMinutes(50),
signingCredentials: signinCredentials
);
var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);
But token generated through above method gets 401 error on authorization.
I have just remove the entries from appsettings.json file and added them in Progrm.cs as mentioned inhttps://stackoverflow.com/a/74788946 and is now it is working
builder.Services.AddAuthentication().AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = "https://localhost:7134",
ValidAudience = "https://localhost:7134",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_securityKey))
};
});
You can try using Phoesion.DevJwt for generating/consuming tokens for development and (system) testing, NOT for production.
dotnet tool install --global phoesion.devjwt.cli
dotnet devjwt create myApi --email [email protected]
appsetting.Development.json
"Authentication": {
"Schemes": {
"Bearer": {
"ValidAudience": "myApi",
"ValidIssuer": "phoesion.devjwt",
"SigningKeys": [
{
"Issuer": "phoesion.devjwt",
"Value": "c29tZV9kZWZhdWx0X2tleV9mb3JfZGV2cw=="
}
]
}
}
}
You can now use the token for your requests.
curl -i -H "Authorization: Bearer {token}" https://localhost:{port}/secret
You can generate token programmatically using the TokenGenerator
like so :
var token = TokenGenerator.Create(audience, email, username)
.ExpiresIn(TimeSpan.FromDays(365))
.Build();
You can also have a look at the console app sample project
Disclosure : I am the developer of this library