Sunday 22 January 2023

JWT authentication in ASP.NET Core WebAPI

 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 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 allows you to describe the structure of your APIs so that machines can read them.

Swashbuckle is an open-source project for generating Swagger documents for Web APIs that are built with ASP.NET Core MVC.

First, Create a New Project and select ASP.NET Core Web Application. 

Create an Authenticate Controller

Create below 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 == "test")
      {
          user = new LoginModel { UserName = "test", Password = "123456" };
      }
      return user;
  }

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

To use the JWT Token and Swagger, we need to install the below two into our project.


Add below functions in Authenticate controller class.
  [HttpGet(nameof(Get))]
  public async Task<IEnumerable<string>> Get()
  {
      var accessToken = await HttpContext.GetTokenAsync("access_token");
      return new string[] { accessToken };
  }

  [HttpGet(nameof(GetName))]
  public async Task<string> GetName()
  {
      return "Suraj Kumar Maddheshiya";
  }

  [HttpGet(nameof(GetAddress))]
  [AllowAnonymous]
  public async Task<string> GetAddress()
  {
      return "Delhi";
  }


Add this model class in project, 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; }
  }

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 below code in 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": "http://localhost:28912"
  },

below method gets called by the runtime. Use this method in Startup.cs to add services to the container.

  public void ConfigureServices(IServiceCollection services)
  {
    services.AddControllers();
    services.AddMvc();
    services.AddSwaggerGen(c =>
    {
                c.SwaggerDoc("v1", new OpenApiInfo
                {
                    Title = "JWT Token Authentication API",
                    Description = "ASP.NET Core 3.1 Web API",
                    Version = "v1"
                });

                // To Enable authorization using Swagger (JWT)  
                c.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\"",
                });

                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                          new OpenApiSecurityScheme
                            {
                                Reference = new OpenApiReference
                                {
                                    Type = ReferenceType.SecurityScheme,
                                    Id = "Bearer"
                                }
                            },
                            new string[] {}
                    }
                });
            });

    services.AddAuthentication(option =>
    {
  option.DefaultAuthenticateScheme =Microsoft.AspNetCore.Authentication.JwtBearer
                                            .JwtBearerDefaults.AuthenticationScheme;
       ption.DefaultChallengeScheme = Microsoft.AspNetCore.Authentication.JwtBearer
                                            .JwtBearerDefaults.AuthenticationScheme;
       option.DefaultScheme = Microsoft.AspNetCore.Authentication.JwtBearer
                                            .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"]  
         };
       });
  }

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

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
     {
         if (env.IsDevelopment())
         {
             app.UseDeveloperExceptionPage();
             app.UseSwagger();
             app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json",
                                                        "DotnetCoreWebAPI_Demo v1"));
         }

         //app.UseHttpsRedirection();
         app.UseRouting();
         app.UseAuthentication();
         app.UseAuthorization();
         app.UseEndpoints(endpoints =>
         {
             endpoints.MapControllers();
         });

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

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


open Login url panel in above screenshot. Pass the parameters to generate the token and Then click on Execute Button -> Your token will be generated!


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


Now every method in this document has been authorized!
If you found this article helps you, please give it a clap 👏

Reference: https://medium.com/https://www.c-sharpcorner.com/https://javascript.plainenglish.io/

0 comments:

Post a Comment

Topics

ADFS (1) ADO .Net (1) Ajax (1) Angular (43) Angular Js (15) ASP .Net (14) Authentication (4) Azure (3) Breeze.js (1) C# (47) CD (1) CI (2) CloudComputing (2) Coding (7) CQRS (1) CSS (2) Design_Pattern (6) DevOps (4) DI (3) Dotnet (8) DotnetCore (16) Entity Framework (2) ExpressJS (4) Html (4) IIS (1) Javascript (17) Jquery (8) Lamda (3) Linq (11) microservice (3) Mongodb (1) MVC (46) NodeJS (8) React (11) SDLC (1) Sql Server (32) SSIS (3) SSO (1) TypeScript (1) UI (1) UnitTest (1) WCF (14) Web Api (15) Web Service (1) XMl (1)

Dotnet Guru Archives