JWT (JSON web token) Bearer Authentication and Authorization for APIs has become more and more popular in the realm of web development. It is an open standard that allows developers to transmit data between parties as a JSON object in a secure way. In this programming tutorial, we will explain the setup of JWT with ASP.NET core web applications.
Sample Application with JWT Authentication
First things first, let’s start with creating a new ASP.NET Core Web Application. Choose ASP.NET Core Web Application and click Next. See the image below:
New ASP.NET Core Web Application
In the next screen, add the Project Name and select the folder location to save the project:
Add Project Name
Next, choose the API with no authentication template, shown in the next two images:
API with No Authentication Template
Template Code Structure
Next, we have added two folders to the project, named Services and Middleware. In the Services folder, we have added a class called JwtServices.cs.
Read: Creating a JSON File in C#
Install Nuget Packages
Next, installation of Nuget packages is required. Right-click Dependencies -> Manage Nuget Packages and install both of these packages:
- System.IdentityModel.Tokens.Jwt
- Microsoft.IdentityModel.Tokens
See the following two images for more:
Install System.IdentityModel.Tokens.Jwt
Install Microsoft.IdentityModel.Tokens
Next, we have added the following code to the JwtService class:
using System; using System.Text; using System.Security.Claims; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using Microsoft.Extensions.Configuration; namespace PrjJWTAuthentication.Middleware { public class JwtServices { private string mysecret; private string myexpDate; public void JwtService(IConfiguration config) { mysecret = config.GetSection("JwtConfig").GetSection("secret").Value; myexpDate = config.GetSection("JwtConfig").GetSection("expirationInMinutes").Value; } public string GenerateSecurityToken(string email) { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(mysecret); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Email, email) }), Expires = DateTime.UtcNow.AddMinutes(double.Parse(myexpDate)), SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) }; var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } } }
Next, in the appsettings.config file, we have added the following JwtConfig section:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "JwtConfig": { "secret": "RFv7DrqznYL6nv7DrqdfrenQYO9JxIsWdcjnQYL6nu09f", "expirationInMinutes": 1440 } }
After executing the current API code, we will return some fake weather JSON data in the browser. Add the [Authorize] attribute in the Controller class, as shown here:
[ApiController] [Authorize] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
Read: Validating with JSON with JSON Schema in C#
Installing ASP.NET Core Authentication
Next, we need to bring in the Microsoft.AspNetCore.Authorization and try running the project again. In the project, add a new class inside the Middleware folder, named AuthenticationMiddleware.
Add the Nuget package Microsoft.AspNetCore.Authentication.JwtBearer as depicted here:
Install Microsoft.AspNetCore.Authentication.JwtBearer
The following code snippet is for the AuthenticationMiddleware class:
using System.Text; using Microsoft.IdentityModel.Tokens; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.AspNetCore.Authentication.JwtBearer; namespace PrjJWTAuthentication.Middleware { public class AuthenticationExtension { public static IServiceCollection AddTokenAuthentication(this IServiceCollection services, IConfiguration config) { var secret = config.GetSection("JwtConfig").GetSection("secret").Value; var key = Encoding.ASCII.GetBytes(secret); services.AddAuthentication(x => { x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }) .AddJwtBearer(x => { x.TokenValidationParameters = new TokenValidationParameters { IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = true, ValidateAudience = true, ValidIssuer = "localhost", ValidAudience = "localhost" }; }); return services; } } }
Updating ConfigurationServices
In the Startup.cs class, find the ConfigurationServices and the Configure functions and update them with the following code snippet:
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace PrjJWTAuthentication { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.AddTokenAuthentication(Configuration); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
Next, right-click the Controllers folder and choose Add -> Controller. Pick the API Controller – Empty template and click Add. Name it TokenController. Refer to the following code snippet where we have added in the new controller:
using AuthTest.API.Services; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; namespace AuthTest.API.Controllers { [Route("api/[controller]")] [ApiController] public class TokenController : ControllerBase { private IConfiguration _config; public TokenController(IConfiguration config) { _config = config; } [HttpGet] public string GetRandomToken() { var jwt = new JwtService(_config); var token = jwt.GenerateSecurityToken("[email protected]"); return token; } } }
Run the app and navigate to https://localhost /api/token. It should work now. The API can be tested with Postman or Fiddler tools, which is beyond the scope of this programming tutorial.
Read more ASP.NET programming tutorials.