Create ASP.net Core API Application
Step 1: Open Visual Studio 2019 and Click Create New Project
Step 2: Choose ASP.NET Core Web Application and press NEXT.
Step 3: Enter the Project name, and then click Create
Step 4: Select .NET Core, ASP.NET Core, and ASP.NET Core Web API template (highlighted in the following).
Step 6: Click Create. The Project Structure will be like this
Install NuGet Packages
1. Right click on the project and and select Manage NuGet Package
2. Install the following plugins
- Microsoft.VisualStudio.Web.CodeGeneration.Design
- Microsoft.EntityFrameworkCore.Tools
- Microsoft.EntityFrameworkCore.SqlServer
- System.IdentityModel.Tokens.Jwt
- Microsoft.AspNetCore.Authentication.JwtBearer
Create a Database Connection with the application
Step 1: Create a database named “Inventory“
Step 2: Select New Query button and select the databse to “Inventory”
Step 3: Run this Script . This script will help you to create two table named “Products” and “UserInfo” . This also insert a data row in “Products” and “UserInfo” table.
Create Table Products( ProductId Int Identity(1,1) Primary Key, Name Varchar(100) Not Null, Category Varchar(100), Color Varchar(20), UnitPrice Decimal Not Null, AvailableQuantity Int Not Null) GO Create Table UserInfo( UserId Int Identity(1,1) Not null Primary Key, FirstName Varchar(30) Not null, LastName Varchar(30) Not null, UserName Varchar(30) Not null, Email Varchar(50) Not null, Password Varchar(20) Not null, CreatedDate DateTime Default(GetDate()) Not Null) GO Insert Into UserInfo(FirstName, LastName, UserName, Email, Password) Values ('Inventory', 'Admin', 'InventoryAdmin', 'InventoryAdmin@abc.com', '$admin@2017') INSERT INTO [dbo].[Products]([Name],[Category],[Color],[UnitPrice],[AvailableQuantity]) VALUES ('Shirt','Fashion','Black', 100, 100)
Step 4: Now open “Package Manager Console” in your VS 19 . Copy and run this given context
Scaffold-DbContext “Server=YourServerName;Database=Inventory;Integrated Security=True” Microsoft.EntityFrameworkCore.SqlServer -OutputDir Model
It will generate three .cs files in Model folder. Picture given bellow
You can see a Autogenerated file name InventoryContex.cs . Open that file and comment out two methods
named ‘InventoryContext‘ & ‘OnConfiguring‘. It is a bad practice to have SQL Server Information in C# class.
After commenting out this two move your connection string to appsetting.json file.
"AllowedHosts": "*", "ConnectionStrings": { "InventoryDatabase": "Server= YourServerName;Database=Inventory;Integrated Security=True" },
Then Register the InventoryContext during application startup . Go to Startup.cs and add this two line at the beginning in ConfigureServices(IServiceCollection services) method
var connection = Configuration.GetConnectionString("InventoryDatabase"); services.AddDbContextPool<InventoryContext>(options => options.UseSqlServer(connection));
Build API
Follow this steps to create API controller for Product
Step 1: Right–click on the Controllers folder, click Add, and then choose Controller.
Step 2: Select API –> Select API Controller with actions using the Entity Framework template.
Step 3: Choose the Products model class and InventoryContext context class, and then name the control ProductsController.
After clicking Add, the API is automatically created using the ASP.NET CORE scaffolding code generation technique.
Go to ProductsController.cs and Change the GetProducts() method with this
[HttpGet] public async Task<ActionResult<IEnumerable<Product>>> GetProducts(bool? inStock, int? skip, int? take) { var products = _context.Products.AsQueryable(); if (inStock != null) // Adds the condition to check availability { products = _context.Products.Where(i => i.AvailableQuantity > 0); } if (skip != null) { products = products.Skip((int)skip); } if (take != null) { products = products.Take((int)take); } return await products.ToListAsync(); }
Build the Solution and Run the Project.
Click on Products GET –>Try it out button . Then click Execute. You will See this in the Response body
Create a JWT
Step 1: Create an empty API controller named TokenController .
Step 2: Paste the below JWT configuration into the appsetting.json file.
"Jwt": { "Key": "sdfsdfsjdbf78sdyfssdfsdfbuidfs98gdfsdbf", "Issuer": "JWTTokenAuthenticationServer", "Audience": "JWTTokenPostmanClient", "Subject": "JWTTokenAccessToken" }
TokenController will be like this.
using InventoryService.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using System; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; using System.Threading.Tasks; namespace InventoryService.Controllers { [Route("api/[controller]")] [ApiController] public class TokenController : ControllerBase { public IConfiguration _configuration; private readonly InventoryContext _context; public TokenController(IConfiguration config, InventoryContext context) { _configuration = config; _context = context; } [HttpPost] public async Task<IActionResult> Post(UserInfo _userData) { if (_userData != null && _userData.Email != null && _userData.Password != null) { var user = await GetUser(_userData.Email, _userData.Password); if (user != null) { //create claims details based on the user information var claims = new[] { new Claim(JwtRegisteredClaimNames.Sub, _configuration["Jwt:Subject"]), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()), new Claim("Id", user.UserId.ToString()), new Claim("FirstName", user.FirstName), new Claim("LastName", user.LastName), new Claim("UserName", user.UserName), new Claim("Email", user.Email) }; var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"])); var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken(_configuration["Jwt:Issuer"], _configuration["Jwt:Audience"], claims, expires: DateTime.UtcNow.AddDays(1), signingCredentials: signIn); return Ok(new JwtSecurityTokenHandler().WriteToken(token)); } else { return BadRequest("Invalid credentials"); } } else { return BadRequest(); } } private async Task<UserInfo> GetUser(string email, string password) { return await _context.UserInfo.FirstOrDefaultAsync(u => u.Email == email && u.Password == password); } } }
Build and Run the Application Again.
Click on Token –> POST–> Try it out button, Then Set
"email": "InventoryAdmin@abc.com",
"password": "$admin@2017",
Then click Execute. On Response Body you can see a token generated.
Secure API endpoint
We have a JWT token in our hand now and now we will working on securing our API.
Step 1: Go to Startup.cs and add this in ConfigureServices(IServiceCollection services) method
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.SaveToken = true; options.TokenValidationParameters = new TokenValidationParameters() { ValidateIssuer = true, ValidateAudience = true, ValidAudience = Configuration["Jwt:Audience"], ValidIssuer = Configuration["Jwt:Issuer"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"])) }; });
Step 2: Add app.UseAuthentication(); in Configure(IApplicationBuilder app, IWebHostEnvironment env) method. This will inject the authorization middleware into the Request pipeline.
Step 3: Add authorization attribute to the Product controller.
Build and Run the Application Again.
Now if you go to the Products GET –>Try it out button . Then click Execute. You will See the Response body like this. Because you are not Authorize by your generated Token
Copy the TOKEN and Press Authorize button on the top right corner of the page.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJKV1RUb2tlbkFjY2Vzc1Rva2VuIiwianRpIjoiZjJhM2VlYjEtM2M3MC00YTY5LTljNGYtN2VlYjA4Y2E3MzM3IiwiaWF0IjoiMTAvMjQvMjAyMSA0OjExOjUwIFBNIiwiSWQiOiIxIiwiRmlyc3ROYW1lIjoiSW52ZW50b3J5IiwiTGFzdE5hbWUiOiJBZG1pbiIsIlVzZXJOYW1lIjoiSW52ZW50b3J5QWRtaW4iLCJFbWFpbCI6IkludmVudG9yeUFkbWluQGFiYy5jb20iLCJleHAiOjE2MzUxNzgzMTEsImlzcyI6IkpXVFRva2VuQXV0aGVudGljYXRpb25TZXJ2ZXIiLCJhdWQiOiJKV1RUb2tlblBvc3RtYW5DbGllbnQifQ.9mlq8XrMxe0Pbe1mABZ3Zzq5b1J_D_fA0Kw4l_VLAe0
If you unable to find Authorize button on the top right corner just follow this short blog.
How to add an authorize button in Swagger UI using asp.net core
Paste the token here and click Authorize Button.
Now you are Authorized and recheck Products GET –>Try it out button . Then click Execute.
This time you will find your desired output.
Check this on GitHub and Download this project –> JWTToken