πŸ‘¨β€πŸ’» Authentication And Authorization In .NET Core Web API Using JWT Token And Swagger UI

Introduction

 
This article is meant to make the process of authentication and authorization easier using JSON Web Tokens and also to check the entire process with Swagger UI rather than PostMan.
 

What is ASP.Net Core?

 
ASP.NET Core is an open-source and cloud-optimized web framework for developing modern web applications that can be developed and run on Windows, Linux, and Mac. It includes the MVC framework, which now combines the features of MVC and Web API into a single web programming framework.
  • ASP.NET Core apps can run on .NET Core or on the full .NET Framework.
  • It was built to provide an optimized development framework for apps that are deployed to the cloud or run on-premises.
  • It consists of modular components with minimal overhead, so you retain flexibility while constructing your solutions.
  • You can develop and run your ASP.NET Core apps cross-platform on Windows, Mac, and Linux

What is a JSON Web Token?

 
A JSON Web Token (or JWT) is simply a JSON payload containing a particular claim. The key property of JWTs is that in order to confirm if they are valid we only need to look at the token itself. ... A JWT is made of 3 parts: the Header, the Payload, and the Signature.
 
Url: https://jwt.io/
 

What is Swagger and how it is useful in ASP.NET Core Web API?

 
Swagger
 
Swagger is a machine-readable representation of a RESTful API that enables support for interactive documentation, client SDK generation, and discoverability.
 
Swashbuckle is an open-source project for generating Swagger documents for Web APIs that are built with ASP.NET Core MVC.
 
Create a New Project and select ASP.NET Core Web Application:
 
Authentication And Authorization In .NET Core Web API Using JWT Token And Swagger UI
 
After clicking to the next button:
 
Authentication And Authorization In .NET Core Web API Using JWT Token And Swagger UI
 
Click on the Create Button to create a Sample API Project.
 

Create an Authenticate Controller 

 
Create this method under the Authenticate Controller:
  1. private string GenerateJSONWebToken(LoginModel userInfo)  
  2.        {  
  3.            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));  
  4.            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);  
  5.   
  6.            var token = new JwtSecurityToken(_config["Jwt:Issuer"],  
  7.              _config["Jwt:Issuer"],  
  8.              null,  
  9.              expires: DateTime.Now.AddMinutes(120),  
  10.              signingCredentials: credentials);  
  11.   
  12.            return new JwtSecurityTokenHandler().WriteToken(token);  
  13.        }  
Create another method for Login Validation to authenticate the user via the Hardcoded method:
  1. private async Task<LoginModel> AuthenticateUser(LoginModel login)  
  2.        {  
  3.            LoginModel user = null;  
  4.   
  5.            //Validate the User Credentials      
  6.            //Demo Purpose, I have Passed HardCoded User Information      
  7.            if (login.UserName == "Jay")  
  8.            {  
  9.                user =  new LoginModel { UserName = "Jay", Password = "123456" };  
  10.            }  
  11.            return user;  
  12.        }  
Create the Login Method to pass the parameters as JSON Format to Validate the User and to generate the Token (JWT).
  1. [AllowAnonymous]  
  2.        [HttpPost(nameof(Login))]  
  3.        public async Task<IActionResult> Login([FromBody] LoginModel data)  
  4.        {  
  5.            IActionResult response = Unauthorized();  
  6.            var user = await AuthenticateUser(data);  
  7.            if (data != null)  
  8.            {  
  9.                var tokenString = GenerateJSONWebToken(user);  
  10.                response = Ok(new { Token = tokenString , Message = "Success" });  
  11.            }  
  12.            return response;  
  13.        }  
Authentication And Authorization In .NET Core Web API Using JWT Token And Swagger UI
 
To use the JWT Token and Swagger, we need to install the above two into our project 
 
Add this Class in Authenticate Controller, as these are the required parameters to validate the User 
  1. public class LoginModel  
  2.     {  
  3.         [Required]  
  4.         public string UserName { getset; }  
  5.         [Required]  
  6.         public string Password { getset; }  
  7.     }  
Authenticate Controller
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel.DataAnnotations;  
  4. using System.IdentityModel.Tokens.Jwt;  
  5. using System.Linq;  
  6. using System.Runtime.InteropServices.WindowsRuntime;  
  7. using System.Text;  
  8. using System.Threading.Tasks;  
  9. using Microsoft.AspNetCore.Authentication;  
  10. using Microsoft.AspNetCore.Authorization;  
  11. using Microsoft.AspNetCore.Mvc;  
  12. using Microsoft.Extensions.Configuration;  
  13. using Microsoft.IdentityModel.Tokens;  
  14.   
  15. namespace AuthenticationandAuthorization.Controllers  
  16. {  
  17.     public class AuthenticateController : BaseController  
  18.     {  
  19.         #region Property  
  20.         /// <summary>  
  21.         /// Property Declaration  
  22.         /// </summary>  
  23.         /// <param name="data"></param>  
  24.         /// <returns></returns>  
  25.         private IConfiguration _config;  
  26.   
  27.         #endregion  
  28.   
  29.         #region Contructor Injector  
  30.         /// <summary>  
  31.         /// Constructor Injection to access all methods or simply DI(Dependency Injection)  
  32.         /// </summary>  
  33.         public AuthenticateController(IConfiguration config)  
  34.         {  
  35.             _config = config;  
  36.         }  
  37.         #endregion  
  38.   
  39.         #region GenerateJWT  
  40.         /// <summary>  
  41.         /// Generate Json Web Token Method  
  42.         /// </summary>  
  43.         /// <param name="userInfo"></param>  
  44.         /// <returns></returns>  
  45.         private string GenerateJSONWebToken(LoginModel userInfo)  
  46.         {  
  47.             var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));  
  48.             var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);  
  49.   
  50.             var token = new JwtSecurityToken(_config["Jwt:Issuer"],  
  51.               _config["Jwt:Issuer"],  
  52.               null,  
  53.               expires: DateTime.Now.AddMinutes(120),  
  54.               signingCredentials: credentials);  
  55.   
  56.             return new JwtSecurityTokenHandler().WriteToken(token);  
  57.         }  
  58.         #endregion  
  59.   
  60.         #region AuthenticateUser  
  61.         /// <summary>  
  62.         /// Hardcoded the User authentication  
  63.         /// </summary>  
  64.         /// <param name="login"></param>  
  65.         /// <returns></returns>  
  66.         private async Task<LoginModel> AuthenticateUser(LoginModel login)  
  67.         {  
  68.             LoginModel user = null;  
  69.   
  70.             //Validate the User Credentials      
  71.             //Demo Purpose, I have Passed HardCoded User Information      
  72.             if (login.UserName == "Jay")  
  73.             {  
  74.                 user =  new LoginModel { UserName = "Jay", Password = "123456" };  
  75.             }  
  76.             return user;  
  77.         }  
  78.         #endregion  
  79.   
  80.         #region Login Validation  
  81.         /// <summary>  
  82.         /// Login Authenticaton using JWT Token Authentication  
  83.         /// </summary>  
  84.         /// <param name="data"></param>  
  85.         /// <returns></returns>  
  86.         [AllowAnonymous]  
  87.         [HttpPost(nameof(Login))]  
  88.         public async Task<IActionResult> Login([FromBody] LoginModel data)  
  89.         {  
  90.             IActionResult response = Unauthorized();  
  91.             var user = await AuthenticateUser(data);  
  92.             if (data != null)  
  93.             {  
  94.                 var tokenString = GenerateJSONWebToken(user);  
  95.                 response = Ok(new { Token = tokenString , Message = "Success" });  
  96.             }  
  97.             return response;  
  98.         }  
  99.         #endregion  
  100.   
  101.         #region Get  
  102.         /// <summary>  
  103.         /// Authorize the Method  
  104.         /// </summary>  
  105.         /// <returns></returns>  
  106.         [HttpGet(nameof(Get))]  
  107.         public async Task<IEnumerable<string>> Get()  
  108.         {  
  109.             var accessToken = await HttpContext.GetTokenAsync("access_token");  
  110.   
  111.             return new string[] { accessToken };  
  112.         }  
  113.   
  114.   
  115.         #endregion  
  116.   
  117.     }  
  118.   
  119.     #region JsonProperties  
  120.     /// <summary>  
  121.     /// Json Properties  
  122.     /// </summary>  
  123.     public class LoginModel  
  124.     {  
  125.         [Required]  
  126.         public string UserName { get; set; }  
  127.         [Required]  
  128.         public string Password { get; set; }  
  129.     }  
  130.     #endregion  
  131. }  
Base Controller
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Threading.Tasks;  
  5. using Microsoft.AspNetCore.Authorization;  
  6. using Microsoft.AspNetCore.Mvc;  
  7.   
  8. // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860  
  9.   
  10. namespace AuthenticationandAuthorization.Controllers  
  11. {  
  12.     [Produces("application/json")]  
  13.     [Route("api/[controller]")]  
  14.     [ApiController]  
  15.     [Authorize(AuthenticationSchemes = Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme)]  
  16.     public class BaseController : ControllerBase  
  17.     {  
  18.         
  19.     }  
  20. }  
Add this Property and Constructor to invoke the appsettings.json Secret JWT Key and its Issuer:
  1. private IConfiguration _config;  
  2.   
  3. public AuthenticateController(IConfiguration config)  
  4.        {  
  5.            _config = config;  
  6.        }  
 Add this code appsettings.json. I have it added as basic key. You can also add it as per your wishes, and under Issuer, add your project URL.
  1. "Jwt": {  
  2.     "Key""Thisismysecretkey",  
  3.     "Issuer""https://localhost:44371"  
  4.   },  
Add this code to the startup.cs file under the Configure Services method to enable the Swagger and also to generate the JWT Bearer Token. 
 
This method gets called by the runtime. Use this method to add services to the container.
  1. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
  2.         {  
  3.             if (env.IsDevelopment())  
  4.             {  
  5.                 app.UseDeveloperExceptionPage();  
  6.             }  
  7.   
  8.             app.UseHttpsRedirection();  
  9.   
  10.             app.UseRouting();  
  11.   
  12.             app.UseAuthorization();  
  13.   
  14.             app.UseEndpoints(endpoints =>  
  15.             {  
  16.                 endpoints.MapControllers();  
  17.             });  
  18.             app.UseAuthentication();  
  19.             // Swagger Configuration in API  
  20.             app.UseSwagger();  
  21.             app.UseSwaggerUI(c =>  
  22.             {  
  23.                 c.SwaggerEndpoint("/swagger/v1/swagger.json""My API v1");  
  24.                   
  25.             });  
  26.   
  27.         }  
This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  1. public void ConfigureServices(IServiceCollection services)  
  2.         {  
  3.             services.AddControllers();  
  4.             // JWT Token Generation from Server Side.  
  5.             services.AddMvc();  
  6.             // Enable Swagger   
  7.             services.AddSwaggerGen(swagger =>  
  8.             {  
  9.                 //This is to generate the Default UI of Swagger Documentation  
  10.                 swagger.SwaggerDoc("v1"new OpenApiInfo  
  11.                 {   
  12.                     Version= "v1",   
  13.                     Title = "JWT Token Authentication API",  
  14.                     Description="ASP.NET Core 3.1 Web API" });  
  15.                 // To Enable authorization using Swagger (JWT)  
  16.                 swagger.AddSecurityDefinition("Bearer"new OpenApiSecurityScheme()  
  17.                 {  
  18.                     Name = "Authorization",  
  19.                     Type = SecuritySchemeType.ApiKey,  
  20.                     Scheme = "Bearer",  
  21.                     BearerFormat = "JWT",  
  22.                     In = ParameterLocation.Header,  
  23.                     Description = "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 12345abcdef\"",  
  24.                 });  
  25.                 swagger.AddSecurityRequirement(new OpenApiSecurityRequirement  
  26.                 {  
  27.                     {  
  28.                           new OpenApiSecurityScheme  
  29.                             {  
  30.                                 Reference = new OpenApiReference  
  31.                                 {  
  32.                                     Type = ReferenceType.SecurityScheme,  
  33.                                     Id = "Bearer"  
  34.                                 }  
  35.                             },  
  36.                             new string[] {}  
  37.   
  38.                     }  
  39.                 });  
  40.             });  
  41.   
  42.             services.AddAuthentication(option =>  
  43.             {  
  44.                 option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;  
  45.                 option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;  
  46.   
  47.             }).AddJwtBearer(options =>  
  48.             {  
  49.                 options.TokenValidationParameters = new TokenValidationParameters  
  50.                 {  
  51.                     ValidateIssuer = true,  
  52.                     ValidateAudience = true,  
  53.                     ValidateLifetime = false,  
  54.                     ValidateIssuerSigningKey = true,  
  55.                     ValidIssuer = Configuration["Jwt:Issuer"],  
  56.                     ValidAudience = Configuration["Jwt:Issuer"],  
  57.                     IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) //Configuration["JwtToken:SecretKey"]  
  58.                 };  
  59.             });  
  60.         }  
When you run the application, you will get the swagger UI as shown below:
 
Authentication And Authorization In .NET Core Web API Using JWT Token And Swagger UI
 
Pass the parameters to generate the token:
  1.  {  
  2.    "Username""Jay",  
  3.    "password""123456"   
  4. }  
Then click on Execute Button -> Your token will be generated!
 
Authentication And Authorization In .NET Core Web API Using JWT Token And Swagger UI
 
Click on the Authorize button and add this token under the Value box.
 
Add the token in the following manner as shown in the example below i.e Bearer token.
 
Click on the Authorize Button 
 
Authentication And Authorization In .NET Core Web API Using JWT Token And Swagger UI
 
Now every method in this document has been authorized!
 
 ........keep learning !!!!