Search code examples
c#jwt.net-7.0

How to generate JWT tokens in .NET 7


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))
    };
});

Solution

  • You can try using Phoesion.DevJwt for generating/consuming tokens for development and (system) testing, NOT for production.

    1. Install the dotnet tool
    dotnet tool install --global phoesion.devjwt.cli
    
    1. Generate token using
    dotnet devjwt create myApi --email [email protected]
    
    1. Configure in 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
    

    Generating token programmatically

    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