JWT Token Generation Process in .Net Core Web API

This is a simple JWT Token Generation Mechanism in .Net Core Web API 2.

Simple JWT Token Generation

 
This is Controller Section of JWT Token Generation.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.IdentityModel.Tokens.Jwt;  
  4. using System.Linq;  
  5. using System.Security.Claims;  
  6. using System.Text;  
  7. using System.Threading.Tasks;  
  8. using Microsoft.AspNetCore.Authorization;  
  9. using Microsoft.AspNetCore.Http;  
  10. using Microsoft.AspNetCore.Mvc;  
  11. using Microsoft.Extensions.Configuration;  
  12. using Microsoft.IdentityModel.Tokens;  
  13. using Models;  
  14. using Repository.Interfaces;  
  15. using CentralSageFlickApi.Helper;  
  16. namespace CentralSageFlickApi.Controllers {  
  17.   public class AccountController: ControllerBase {  
  18.     private readonly IAccountService _accountService;  
  19.     private IConfiguration _config;  
  20.     public AccountController(IConfiguration config, IAccountService accountService) {  
  21.      _config = config;  
  22.      _accountService = accountService;  
  23.     }#  
  24.     region Token Generation  
  25.      [AllowAnonymous]  
  26.      [HttpPost]  
  27.      [Route("~/api/Token/TokenGenerate")]  
  28.     public IActionResult Login([FromBody] LoginModel login) {  
  29.      IActionResult response = Unauthorized();  
  30.      try {  
  31.       if (ModelState.IsValid) {  
  32.        var user = AuthenticateUser(login.Username, login.AppCode);  
  33.        if (user != null) {  
  34.         var passwordString = PasswordGeneration.DecryptString(user.PasswordSalt, user.Password);  
  35.         if (login.Password.Equals(passwordString)) {  
  36.          var tokenString = GenerateJwtToken(user);  
  37.          response = Ok(new {  
  38.           token = tokenString  
  39.          });  
  40.         } else {  
  41.          response = BadRequest(new {  
  42.           message = "Invalid Password!"  
  43.          });  
  44.         }  
  45.        } else {  
  46.         response = BadRequest(new {  
  47.          message = "Invalid User!"  
  48.         });  
  49.        }  
  50.       } else {  
  51.        response = BadRequest(new {  
  52.         message = String.Join(Environment.NewLine, ModelState.Values.SelectMany(v => v.Errors)  
  53.          .Select(v => v.ErrorMessage + " " + v.Exception))  
  54.        });  
  55.       }  
  56.      } catch (Exception ex) {  
  57.       response = BadRequest(new {  
  58.        message = ex.Message.ToString()  
  59.       });  
  60.      }  
  61.      return response;  
  62.     }  
  63.     private string GenerateJwtToken(UserRegisterModel userInfo) {  
  64.      var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));  
  65.      var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);  
  66.      var claims = new [] {  
  67.       new Claim(ClaimTypes.Name, userInfo.Username),  
  68.        new Claim(ClaimTypes.Email, userInfo.Email),  
  69.        new Claim(ClaimTypes.NameIdentifier, userInfo.AppCode),  
  70.        new Claim(ClaimTypes.DateOfBirth, userInfo.AddedDate.ToString("yyyy-MM-dd")),  
  71.        new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())  
  72.      };  
  73.      var token = new JwtSecurityToken(issuer: _config["Jwt:Issuer"],  
  74.       audience: _config["Jwt:Audience"],  
  75.       claims: claims,  
  76.       expires: DateTime.Now.AddMinutes(Convert.ToInt32(_config["Jwt:Expire"])),  
  77.       signingCredentials: credentials);  
  78.      return new JwtSecurityTokenHandler().WriteToken(token);  
  79.     }  
  80.     private UserRegisterModel AuthenticateUser(string userName, string appCode) {  
  81.      UserRegisterModel user = _accountService.CheckUser(userName, appCode);  
  82.      return user;  
  83.     }#  
  84.     endregion  
  85.   }  
  86. }  
Startup.cs
 
This is Startup.cs file.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using Microsoft.AspNetCore.Authentication.JwtBearer;  
  7. using Microsoft.AspNetCore.Builder;  
  8. using Microsoft.AspNetCore.Hosting;  
  9. using Microsoft.AspNetCore.Http;  
  10. using Microsoft.AspNetCore.HttpsPolicy;  
  11. using Microsoft.AspNetCore.Mvc;  
  12. using Microsoft.Extensions.Configuration;  
  13. using Microsoft.Extensions.DependencyInjection;  
  14. using Microsoft.Extensions.Logging;  
  15. using Microsoft.Extensions.Options;  
  16. using Microsoft.IdentityModel.Tokens;  
  17. using Models;  
  18. using Repository.Interfaces;  
  19. using Repository.Services;  
  20. namespace CentralSageFlickApi  
  21. {  
  22.     public class Startup  
  23.     {  
  24.         public Startup(IConfiguration configuration)  
  25.         {  
  26.             Configuration = configuration;  
  27.         }  
  28.         public IConfiguration Configuration { get; }  
  29.         // This method gets called by the runtime. Use this method to add services to the container.  
  30.         public void ConfigureServices(IServiceCollection services)  
  31.         {  
  32.             #region Add CORS    
  33.             services.AddCors(options => options.AddPolicy("Cors", builder =>  
  34.             {  
  35.                 builder  
  36.                 .AllowAnyOrigin()  
  37.                 .AllowAnyMethod()  
  38.                 .AllowAnyHeader();  
  39.             }));  
  40.             #endregion  
  41.             #region JwtToken Authentication  
  42.             services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)  
  43.               .AddJwtBearer(options =>  
  44.               {  
  45.                   options.TokenValidationParameters = new TokenValidationParameters  
  46.                   {                     
  47.                       ValidateIssuer = true,  
  48.                       ValidateAudience = true,  
  49.                       ValidateLifetime = true,  
  50.                       ValidateIssuerSigningKey = true,  
  51.                       ValidIssuer = Configuration["Jwt:Issuer"],  
  52.                       ValidAudience = Configuration["Jwt:Audience"],  
  53.                       IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))  
  54.                   };  
  55.               });  
  56.             #endregion  
  57.             services.Configure<ReadConfig>(Configuration.GetSection("ConnectionString"));  
  58.             services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();  
  59.             services.AddTransient<IAccountService, AccountService>();  
  60.             services.AddTransient<ITheaterService, TheaterService>();  
  61.             services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);  
  62.         }  
  63.         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.  
  64.         public void Configure(IApplicationBuilder app, IHostingEnvironment env)  
  65.         {  
  66.             if (env.IsDevelopment())  
  67.             {  
  68.                 app.UseDeveloperExceptionPage();  
  69.             }  
  70.             else  
  71.             {  
  72.                 // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.  
  73.                 app.UseHsts();  
  74.             }  
  75.             app.UseAuthentication();  
  76.             app.UseCors("Cors");  
  77.             app.UseHttpsRedirection();  
  78.             app.UseStaticFiles();  
  79.             app.UseMvc();  
  80.         }  
  81.     }  
  82. }