Authentication And Authorization In .NET Core Web API Using JWT Token And Swagger UI

Authentication And Authorization In .NET Core Web API Using JWT Token And Swagger UI

ASP.NET Core - JWT - Swagger

ยท

6 min read

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: Json Web Token

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:

Z1.png

After clicking on the Next button:

Z2.png

Click on the Create Button to create a Sample API Project.

Create an Authenticate Controller

Create this method under the Authenticate Controller:

private string GenerateJSONWebToken(LoginModel userInfo)  
       {  
           var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));  
           var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);  

           var token = new JwtSecurityToken(_config["Jwt:Issuer"],  
             _config["Jwt:Issuer"],  
             null,  
             expires: DateTime.Now.AddMinutes(120),  
             signingCredentials: credentials);  

           return new JwtSecurityTokenHandler().WriteToken(token);  
       }

Create another method for Login Validation to authenticate the user via the Hardcoded method:

private async Task<LoginModel> AuthenticateUser(LoginModel login)  
       {  
           LoginModel user = null;  

           //Validate the User Credentials      
           //Demo Purpose, I have Passed HardCoded User Information      
           if (login.UserName == "Jay")  
           {  
               user =  new LoginModel { UserName = "Jay", Password = "123456" };  
           }  
           return user;  
       }

Create the Login Method to pass the parameters as JSON Format to Validate the User and to generate the Token (JWT).

[AllowAnonymous]  
       [HttpPost(nameof(Login))]  
       public async Task<IActionResult> Login([FromBody] LoginModel data)  
       {  
           IActionResult response = Unauthorized();  
           var user = await AuthenticateUser(data);  
           if (data != null)  
           {  
               var tokenString = GenerateJSONWebToken(user);  
               response = Ok(new { Token = tokenString , Message = "Success" });  
           }  
           return response;  
       }

Required Packages

Z3.png

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.

public class LoginModel  
    {  
        [Required]  
        public string UserName { get; set; }  
        [Required]  
        public string Password { get; set; }  
    }

Authenticate Controller

namespace AuthenticationandAuthorization.Controllers  
{  
    public class AuthenticateController : BaseController  
    {  
        #region Property  
        /// <summary>  
        /// Property Declaration  
        /// </summary>  
        /// <param name="data"></param>  
        /// <returns></returns>  
        private IConfiguration _config;  

        #endregion  

        #region Contructor Injector  
        /// <summary>  
        /// Constructor Injection to access all methods or simply DI(Dependency Injection)  
        /// </summary>  
        public AuthenticateController(IConfiguration config)  
        {  
            _config = config;  
        }  
        #endregion  

        #region GenerateJWT  
        /// <summary>  
        /// Generate Json Web Token Method  
        /// </summary>  
        /// <param name="userInfo"></param>  
        /// <returns></returns>  
        private string GenerateJSONWebToken(LoginModel userInfo)  
        {  
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));  
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);  

            var token = new JwtSecurityToken(_config["Jwt:Issuer"],  
              _config["Jwt:Issuer"],  
              null,  
              expires: DateTime.Now.AddMinutes(120),  
              signingCredentials: credentials);  

            return new JwtSecurityTokenHandler().WriteToken(token);  
        }  
        #endregion  

        #region AuthenticateUser  
        /// <summary>  
        /// Hardcoded the User authentication  
        /// </summary>  
        /// <param name="login"></param>  
        /// <returns></returns>  
        private async Task<LoginModel> AuthenticateUser(LoginModel login)  
        {  
            LoginModel user = null;  

            //Validate the User Credentials      
            //Demo Purpose, I have Passed HardCoded User Information      
            if (login.UserName == "Jay")  
            {  
                user =  new LoginModel { UserName = "Jay", Password = "123456" };  
            }  
            return user;  
        }  
        #endregion  

        #region Login Validation  
        /// <summary>  
        /// Login Authenticaton using JWT Token Authentication  
        /// </summary>  
        /// <param name="data"></param>  
        /// <returns></returns>  
        [AllowAnonymous]  
        [HttpPost(nameof(Login))]  
        public async Task<IActionResult> Login([FromBody] LoginModel data)  
        {  
            IActionResult response = Unauthorized();  
            var user = await AuthenticateUser(data);  
            if (data != null)  
            {  
                var tokenString = GenerateJSONWebToken(user);  
                response = Ok(new { Token = tokenString , Message = "Success" });  
            }  
            return response;  
        }  
        #endregion  

        #region Get  
        /// <summary>  
        /// Authorize the Method  
        /// </summary>  
        /// <returns></returns>  
        [HttpGet(nameof(Get))]  
        public async Task<IEnumerable<string>> Get()  
        {  
            var accessToken = await HttpContext.GetTokenAsync("access_token");  

            return new string[] { accessToken };  
        }  


        #endregion  

    }  

    #region JsonProperties  
    /// <summary>  
    /// Json Properties  
    /// </summary>  
    public class LoginModel  
    {  
        [Required]  
        public string UserName { get; set; }  
        [Required]  
        public string Password { get; set; }  
    }  
    #endregion  
}

Base Controller

namespace AuthenticationandAuthorization.Controllers  
{  
    [Produces("application/json")]  
    [Route("api/[controller]")]  
    [ApiController]  
    [Authorize(AuthenticationSchemes = Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme)]  
    public class BaseController : ControllerBase  
    {  

    }  
}

Add this Property and Constructor to invoke the appsettings.json Secret JWT Key and its Issuer:

private IConfiguration _config;  

public AuthenticateController(IConfiguration config)  
       {  
           _config = config;  
       }

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.

"Jwt": {  
    "Key": "Thisismysecretkey",  
    "Issuer": "https://localhost:44371"  
  },

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.

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)  
        {  
            if (env.IsDevelopment())  
            {  
                app.UseDeveloperExceptionPage();  
            }  

            app.UseHttpsRedirection();  

            app.UseRouting();  

            app.UseAuthorization();  

            app.UseEndpoints(endpoints =>  
            {  
                endpoints.MapControllers();  
            });  
            app.UseAuthentication();  
            // Swagger Configuration in API  
            app.UseSwagger();  
            app.UseSwaggerUI(c =>  
            {  
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API v1");  

            });  

        }

This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

public void ConfigureServices(IServiceCollection services)  
        {  
            services.AddControllers();  
            // JWT Token Generation from Server Side.  
            services.AddMvc();  
            // Enable Swagger   
            services.AddSwaggerGen(swagger =>  
            {  
                //This is to generate the Default UI of Swagger Documentation  
                swagger.SwaggerDoc("v1", new OpenApiInfo  
                {   
                    Version= "v1",   
                    Title = "JWT Token Authentication API",  
                    Description="ASP.NET Core 3.1 Web API" });  
                // To Enable authorization using Swagger (JWT)  
                swagger.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()  
                {  
                    Name = "Authorization",  
                    Type = SecuritySchemeType.ApiKey,  
                    Scheme = "Bearer",  
                    BearerFormat = "JWT",  
                    In = ParameterLocation.Header,  
                    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\"",  
                });  
                swagger.AddSecurityRequirement(new OpenApiSecurityRequirement  
                {  
                    {  
                          new OpenApiSecurityScheme  
                            {  
                                Reference = new OpenApiReference  
                                {  
                                    Type = ReferenceType.SecurityScheme,  
                                    Id = "Bearer"  
                                }  
                            },  
                            new string[] {}  

                    }  
                });  
            });  

            services.AddAuthentication(option =>  
            {  
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;  
                option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;  

            }).AddJwtBearer(options =>  
            {  
                options.TokenValidationParameters = new TokenValidationParameters  
                {  
                    ValidateIssuer = true,  
                    ValidateAudience = true,  
                    ValidateLifetime = false,  
                    ValidateIssuerSigningKey = true,  
                    ValidIssuer = Configuration["Jwt:Issuer"],  
                    ValidAudience = Configuration["Jwt:Issuer"],  
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) //Configuration["JwtToken:SecretKey"]  
                };  
            });  
        }

When you run the application, you will get the swagger UI as shown below:

Z4.png

Pass the parameters to generate the token:

{  
   "Username": "Jay",  
   "password": "123456"   
}

Then click on Execute Button -> Your token will be generated!

Z5.png

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

Z6.png

Now every method in this document has been authorized!

Git-Hub - Source Code

Thank you for reading, please let me know your questions, thoughts, or feedback in the comments section. I appreciate your feedback and encouragement.

bmc-button.png

........keep learning !!!!