Angular 8 CRUD With OAuth2.0 In WebAPI - Part One

Introduction

 
This tutorial is divided into two parts. In the first part (this one), we will develop our Web API and secure the Web API using OAuth 2.0. In the second part, we will develop the front-end Angular app to consume the Web API.
The project code files, database backup, and database script are attached with this article or you can download these from this link to Project Source Code.
 

How will it work?

 
The first time a user requests the token and passes the credentials for that, we will create a Provider class which receives that HTTP request and validates the credentials. If the credentials are correct, it will register the user and will generate a specific token against this request and pass back to the client. Now, the client will receive this token and will store for the next HTTP request. When a client will request for a resource, it will pass this token into the headers of the HTTP request.
 
Start with the creation of a database with the name OauthDb, containing two tables - User and Product.
 
User Table
 
 
Product Table
 
 
 
Step 1
 
Create an ASP.NET project with the name WebAPI_Oauth.
 
 
Select Web API
 
 
Step 2
 
Add the following NuGet packages
  • Microsoft.Owin
  • Microsoft.Owin.Host.SystemWeb
  • Microsoft.Owin.Security.OAuth
  • Microsoft.Owin.Security
  • Microsoft.AspNet.Identity.Owin
  • Microsoft.Owin.Cors
Step 3
 
Add Entity Model.
 
 
Step 4
 
Add a new folder with the name "Provider" and inside the folder, add new a class OauthProvider.cs.
 
 
OauthProvider.cs
  1. using Microsoft.Owin.Security.OAuth;  
  2. using System;  
  3. using System.Collections.Generic;  
  4. using System.Linq;  
  5. using System.Security.Claims;  
  6. using System.Threading.Tasks;  
  7. using System.Web;  
  8. using WebAPI_Oauth.Models;  
  9.   
  10. namespace WebAPI_Oauth.Provider  
  11. {  
  12.     public class OauthProvider : OAuthAuthorizationServerProvider  
  13.     {  
  14.         public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)  
  15.         {  
  16.             //First request will come here, this method will validate the request wheather it has crendtials(UserName and Password) if the request not contain username and   
  17.            //password the request will reject from here not proceded any further  
  18.             context.Validated();   
  19.         }  
  20.         public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)  
  21.         {  
  22.             //If the request has valid and it contain username and password than this method will check correct crenstials and than generate a valid token  
  23.             var identity = new ClaimsIdentity(context.Options.AuthenticationType); //it will check the authenticate type  
  24.   
  25.             using (var db = new DataContext())  
  26.             {  
  27.                 if (db != null)  
  28.                 {  
  29.                     var user = db.Users.Where(o => o.UserName == context.UserName && o.Password == context.Password).FirstOrDefault();//LINQ query checking the username   
  30.                     //and password from db  
  31.                     if (user != null)  
  32.                     {  
  33.                         //Store information againest the request  
  34.                         identity.AddClaim(new Claim("UserName", context.UserName));  
  35.                         identity.AddClaim(new Claim("LoggedOn", DateTime.Now.ToString()));  
  36.                         context.Validated(identity);  
  37.                     }  
  38.                     else  
  39.                     {  
  40.                         context.SetError("Wrong Crendtials""Provided username and password is incorrect");  
  41.                         context.Rejected();  
  42.   
  43.                     }  
  44.                 }  
  45.                 else  
  46.                 {  
  47.                     context.SetError("Wrong Crendtials""Provided username and password is incorrect");  
  48.                     context.Rejected();  
  49.                 }  
  50.                 return;  
  51.             }  
  52.         }  
  53.     }  

Step 5
 
Delete the Global.asax class because we will not use this class in this project. We will create our own startup class so create a startup class and paste this code into that.
 
Startup.cs
  1. using Microsoft.Owin;  
  2. using Microsoft.Owin.Cors;  
  3. using Microsoft.Owin.Security.OAuth;  
  4. using Owin;  
  5. using System;  
  6. using System.Collections.Generic;  
  7. using System.Linq;  
  8. using System.Web;  
  9. using System.Web.Http;  
  10. using WebAPI_Oauth.Provider;  
  11.   
  12. namespace WebAPI_Oauth  
  13. {  
  14.    
  15.         public class Startup  
  16.         {  
  17.             public void ConfigureAuth(IAppBuilder app)  
  18.             {  
  19.                 app.UseCors(CorsOptions.AllowAll);//this is very important line cross orgin source(CORS)it is used to enable cross-site HTTP requests    
  20.                                                   //For security reasons, browsers restrict cross-origin HTTP requests   
  21.             var OAuthOptions = new OAuthAuthorizationServerOptions  
  22.                 {  
  23.                     AllowInsecureHttp = true,  
  24.                     TokenEndpointPath = new PathString("/token"),  
  25.                     AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(60),//token expiration time  
  26.                     Provider = new OauthProvider()  
  27.                 };  
  28.   
  29.                 app.UseOAuthBearerTokens(OAuthOptions);  
  30.                 app.UseOAuthAuthorizationServer(OAuthOptions);  
  31.                 app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());  
  32.   
  33.                 HttpConfiguration config = new HttpConfiguration();  
  34.                 WebApiConfig.Register(config);//register the request  
  35.             }  
  36.   
  37.             public void Configuration(IAppBuilder app)  
  38.             {  
  39.                 ConfigureAuth(app);  
  40.                 GlobalConfiguration.Configure(WebApiConfig.Register);  
  41.             }  
  42.   
  43.         }  
  44.      

Step 6
 
Create WebAPI2 Controller and name it ProductController. 
 
 
ProductController.cs
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Net;  
  5. using System.Net.Http;  
  6. using System.Web.Http;  
  7. using WebAPI_Oauth.Models;  
  8.   
  9. namespace WebAPI_Oauth.Controllers  
  10. {  
  11.         [RoutePrefix("Api/Product")]//This is Route prefix filter which will be added in the URL for this specific controller  
  12.         [Authorize]//This filter redirects the request to the provider class first request will authenticate if authentication successful than it will come to here  
  13.         public class ProductController : ApiController  
  14.         {  
  15.             [HttpGet]  
  16.             [Route("GetProducts")]  
  17.             public List<Product> GetProducts()//This is th get method which get all the products from the db and return  
  18.             {  
  19.             List<Product> productList = new List<Product>();  
  20.             using (DataContext dataContext=new DataContext())  
  21.             {  
  22.                 productList = dataContext.Products.ToList();  
  23.             }  
  24.             return productList;  
  25.             }  
  26.             [HttpGet]  
  27.             [Route("GetProductById/{Id}")]  
  28.             public Product GetProductById(string Id)//This is th get method which get one record on the basis of ID   
  29.         {  
  30.                 Product product = new Product();  
  31.                 using (DataContext dataContext = new DataContext())  
  32.             {  
  33.                 product = dataContext.Products.Find(Convert.ToInt32(Id));  
  34.             }                
  35.                 return (product);  
  36.             }  
  37.             [HttpPost]  
  38.             [Route("InsertProduct")]  
  39.             public IHttpActionResult Create(Product product)//This method will insert the product into db  
  40.             {  
  41.             using (DataContext dataContext = new DataContext())  
  42.             {  
  43.                 if (!ModelState.IsValid)  
  44.                 {  
  45.                     return BadRequest(ModelState);  
  46.                 }  
  47.                 else  
  48.                 {  
  49.                     dataContext.Products.Add(product);  
  50.                     dataContext.SaveChanges();  
  51.                     return Ok(product);  
  52.                 }  
  53.             }                 
  54.             }  
  55.             [HttpPut]  
  56.             [Route("UpdateProduct")]  
  57.             public IHttpActionResult Update(Product product)//Update method will update the product  
  58.             {  
  59.             using (DataContext dataContext = new DataContext())  
  60.             {  
  61.                 if (ModelState.IsValid)  
  62.                 {  
  63.                     dataContext.Entry(product).State = System.Data.Entity.EntityState.Modified;  
  64.                     dataContext.SaveChanges();  
  65.                     return Ok(product);  
  66.                 }  
  67.                 else  
  68.                 {  
  69.                     return BadRequest(ModelState);  
  70.                 }  
  71.             }                        
  72.             }  
  73.             [HttpDelete]  
  74.             [Route("DeleteProduct/{Id}")]  
  75.             public IHttpActionResult Delete(int Id)//this method will Delete the record  
  76.             {  
  77.             using (DataContext dataContext = new DataContext())  
  78.             {  
  79.                 Product product = dataContext.Products.Find(Convert.ToInt32(Id));  
  80.                 if (product == null) { return NotFound(); }  
  81.                 else  
  82.                 {  
  83.                     dataContext.Products.Remove(product);  
  84.                     dataContext.SaveChanges();  
  85.                     return Ok(product);  
  86.                 }  
  87.             }                           
  88.             }  
  89.         }  

Step 10
 
Run this project and test this Web API using POSTMAN.
 

 
Step 11
 
Now, paste this token in authorization and call the GetProducts method.
 
 

Conclusion

 
In this article, we have successfully developed the Web API project using OAuth2.0 and also implemented the CRUD methods in ProductController. The front-end of this project is in Part 2 where we will consume this Web API and will perform the CRUD operations. If you face any problem or you have any query, please feel free to comment in the comment section below.
 
Don’t forget to like and share it.