How To Implement Token Based Authentication Using Web API, Entity Framework, And Angular 7

Introduction

 
In this article, we will perform authentication using Web API, Entity Framework, and Angular 7 web applications. We are using the SQL database as the back-end with Entity Framework. In the middle layer, we will use Web API for data connectivity between the database and the front-end application. On the UI side, we will use an Angular 7 application.
 
We are using SQL Server for the database, Visual Studio for the Web API, and Visual Studio Code for creating the Angular application.
 
Step 1 Create a Database Table and Stored Procedure
 
Open SQL Server and create a database table as in the below code. After the table is created successfully, insert some user data for authentication and create one stored procedure. If you have already had this type of table, you can skip this step.
  1. -- create table  
  2.   
  3. CREATE TABLE [dbo].[UserLogin](  
  4.     [Id] [int] IDENTITY(1,1) NOT NULL,  
  5.     [UserName] [varchar](50) NULL,  
  6.     [UserPassword] [varchar](50) NULL,  
  7.     [UserEmail] [varchar](50) NULL,  
  8.     [UserRole] [varchar](50) NULL,  
  9.  CONSTRAINT [PK_UserLogin] PRIMARY KEY CLUSTERED   
  10. (  
  11.     [Id] ASC  
  12. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ONON [PRIMARY]  
  13. ON [PRIMARY]  
  14.   
  15. GO  
  16.   
  17.   
  18.   
  19. -- insert data in table  
  20. insert into UserLogin(UserName,UserPassword,UserEmail,UserRole)  
  21. values ('admin','123456','[email protected]','admin')  
  22.   
  23. -- create store procedure   
  24. Create PROCEDURE [dbo].[EF_UserLogin]   
  25.     @UserName varchar(50)=null,  
  26.     @UserPassword varchar(50)=null  
  27. AS  
  28. BEGIN  
  29.       
  30.     SET NOCOUNT ON;  
  31.          
  32.     SELECT  UserName,UserPassword,UserEmail,UserRole from UserLogin where UserName=@UserName and UserPassword=@UserPassword  
  33. END  

Step 2 - Create a New Web API Project
 
Now, open Visual Studio, create a Web API project as you see in the below image. Here, select the "No Authentication" option because we don't want to use a membership database.
 
Open Visual Studio >> File >> New >> Poject >> Select Web API. 
 
 
 
Click OK.
 
Step 3 - Install Required Packages 
 
Now, find NuGet Package Manager, click on "Install". You can also use the Package Manager Console. In the Package Manager Console window, type the following command. After installation, these packages will be available in references.
 
Install-Package name of the package
  • Microsoft.Owin.Host.SystemWeb
  • Microsoft.Owin.Security.OAuth
  • Microsoft.Owin.Cors
Here, we also need to install a package for enabling CORS. This dependency is used for allowing our origin (domain) of the front-end on the Web API.
 
Microsoft.AspNet.WebApi.Cors 
 
 
 
Step 4 - Now, Add ASO.NET Entity Data Model
 
Now, we are creating a new ADO.NET Entity Data Model. Select the stored procedure for checking the user login credentials, as you see in the given image.
 
 
 
Step 5 - Create a Startup.cs Class File
 
Here, we need to create a new class file to implement the code configuration provider and create an instance of class MyAuthProvider. 
  1. using Microsoft.Owin;  
  2. using Microsoft.Owin.Security.OAuth;  
  3. using Owin;  
  4. using System;  
  5. using System.Web;  
  6. using System.Web.Http;  
  7.   
  8. [assembly: OwinStartup(typeof(TokenBaseAuthentication.Startup))]  
  9. namespace TokenBaseAuthentication  
  10. {  
  11.     public class Startup  
  12.     {  
  13.      
  14.         public void Configuration(IAppBuilder app)  
  15.         {  
  16.   
  17.             app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);  
  18.   
  19.             var myProvider = new MyAuthProvider();  
  20.             OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions  
  21.             {  
  22.                 AllowInsecureHttp = true,  
  23.                 TokenEndpointPath = new PathString("/token"),  
  24.                 AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30),  
  25.                 Provider = myProvider  
  26.             };  
  27.             app.UseOAuthAuthorizationServer(options);  
  28.             app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());  
  29.   
  30.   
  31.             HttpConfiguration config = new HttpConfiguration();  
  32.             WebApiConfig.Register(config);  
  33.         }  
  34.   
  35.     }    
  36. }  
Step 6 - Create MyAuthProvider.cs Class File
 
Now, let us create one more class to implement OAuthAuthorizationServerProvider and call our ADO.NET Entity Model. This model validates the user from a database. 
  1. using Microsoft.Owin.Security.OAuth;  
  2. using System.Linq;  
  3. using System.Security.Claims;  
  4. using System.Threading.Tasks;  
  5. using System.Web;  
  6.   
  7. namespace TokenBaseAuthentication  
  8. {  
  9.     public class MyAuthProvider : OAuthAuthorizationServerProvider  
  10.     {  
  11.   
  12.         public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)  
  13.         {  
  14.             context.Validated();  
  15.         }  
  16.   
  17.         public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)  
  18.         {  
  19.             var identity = new ClaimsIdentity(context.Options.AuthenticationType);  
  20.   
  21.             UserEntities obj = new UserEntities();  
  22.             var userdata = obj.EF_UserLogin(context.UserName, context.Password).FirstOrDefault();  
  23.             if (userdata != null)  
  24.             {  
  25.                 identity.AddClaim(new Claim(ClaimTypes.Role, userdata.UserRole));  
  26.                 identity.AddClaim(new Claim(ClaimTypes.Name, userdata.UserName));  
  27.                 context.Validated(identity);  
  28.             }  
  29.             else  
  30.             {  
  31.                 context.SetError("invalid_grant""Provided username and password is incorrect");  
  32.                 context.Rejected();  
  33.             }  
  34.         }  
  35.   
  36.     }  
  37.   
  38. }  
Open the Web API config file and add this code.
  1. config.EnableCors();   
Now, we are done with almost all the required code for Web API application.
 
Step 7 - Create New Angular Project 
 
Now, we are creating a new Angular application for UI. Here, I am using VS Code IDE for front-end; you can use any IDE for creating the Angular application. Given below is the command for Angular application creation. One thing to keep in mind before Angular installation is that you have already installed Node and AngularCLI in your system.
 
ng new TokenBaseAuth 
 
 
 
Step 8 - Create New Service in Angular
 
Now, we are creating a new service for calling the Web API. As you can see, here, we are defining the API URL for sending a request to the server.
 
ng generate service myservice 
  1. import { Injectable } from '@angular/core';    
  2. import { HttpClient , HttpHeaders,HttpParams } from '@angular/common/http';    
  3.   
  4. @Injectable({    
  5.   providedIn: 'root'    
  6. })    
  7. export class MyserviceService {    
  8.     
  9.   constructor(private http: HttpClient) { }    
  10.     
  11.     
  12.   postData(data): any {      
  13.     const body = new HttpParams()          
  14.     .set('grant_type', data.grant_type)          
  15.     .set('username', data.username)    
  16.     .set('password', data.password)    
  17.     return this.http.post('http://localhost:64793/token', body.toString(), {observe: 'response',    
  18.       headers: { 'Content-Type''application/x-www-form-urlencoded' },    
  19.     });    
  20.   }    
  21. }   
Step 9 - Create New login Component  
 
Now, let us create a login component using the following command and write the given code in that component. 
 
ng generate component login
  1. // login.component.ts code
  2. import { Component, OnInit } from '@angular/core';  
  3. import { FormGroup, FormControl, Validators } from '@angular/forms';  
  4. import { MyserviceService } from '../myservice.service'  
  5.  @Component({  
  6.   selector: 'app-login',  
  7.   templateUrl: './login.component.html',  
  8.   styleUrls: ['./login.component.css']  
  9. })  
  10. export class LoginComponent implements OnInit {  
  11.   form: FormGroup;  
  12.   successmsg: any;  
  13.   errmsg: any;  
  14.   constructor(private Userservice : MyserviceService) { }  
  15.   ngOnInit() {  
  16.     this.form = new FormGroup({  
  17.       username: new FormControl('', [Validators.required]),   
  18.       password: new FormControl('', [Validators.required, Validators.minLength(6)]),  
  19.       grant_type: new FormControl('password'),  
  20.      });  
  21.     }  
  22.   
  23.   
  24. onSubmit()  
  25.   {     
  26.       this.Userservice.postData(this.form.value)  
  27.                      .subscribe(res => {    
  28.                        if (res.status === 200) { 
  29.                         this.successmsg = 'token - ' + res.body.access_token;                                                                                     localStorage.setItem('access_token', res.body.access_token);  
  30.                         } else {  
  31.                           this.errmsg = res.status + ' - ' + res.statusText;  
  32.                           }  
  33.                          },  
  34.                        err => {                                 
  35.                         if (err.status === 401  ) {  
  36.                           this.errmsg = 'Invalid username or password.';  
  37.                            }   
  38.                           else if (err.status === 400  ) {  
  39.                            this.errmsg = 'Invalid username or password.';  
  40.                           }   
  41.                           else {  
  42.                           this.errmsg ="Invalid username or password";  
  43.                            }  
  44.                         });  
  45.         }   
  46. }  
Open the login.component.html file and write the code given below. 
  1. <div class="container">  
  2.   <div class="row">  
  3.         
  4.     <div class="col-md-4"></div>  
  5.     <div class="col-md-4 jumbotron">  
  6.         <h3>Login</h3><hr>  
  7.         <form [formGroup]="form" (ngSubmit)="onSubmit()" novalidate>  
  8.             <div class="form-group">  
  9.                 <label for="uname">User Name:</label>  
  10.                 <div class="input-group">  
  11.                   <div class="input-group-addon glyphicon glyphicon-user"></div>  
  12.                   <input type="text" placeholder="username" formControlName="username" maxlength="20" class="form-control">  
  13.                 </div>  
  14.                 <div class="alert alert-danger" *ngIf="form.controls['username'].dirty && form.controls['username'].invalid">  
  15.                     <div *ngIf="form.controls['username'].hasError('required')">Username is required</div>  
  16.                   </div>  
  17.             </div>  
  18.     
  19.             <div class="form-group">  
  20.                 <label for="pwd">Password:</label>  
  21.                 <div class="input-group">  
  22.                   <div class="input-group-addon glyphicon glyphicon-lock"></div>  
  23.                   <input type="password" placeholder="password" formControlName="password"   class="form-control">  
  24.                 </div>  
  25.                 <div class="alert alert-danger" *ngIf="form.controls['password'].dirty && form.controls['password'].invalid">  
  26.                     <div *ngIf="form.controls['password'].hasError('required')">Password is required</div>  
  27.                     <div *ngIf="form.controls['password'].hasError('minlength')">Password must minlength 6 characters long.</div>  
  28.                 </div>  
  29.             </div>  
  30.          <div class="form-group"                    
  31.                 <input type="submit" value="Login" class="btn btn-primary" [disabled]="form.invalid" >   
  32.             </div>  
  33.             <div class="form-group">  
  34.               <div class="col-md-12 alert alert-danger" *ngIf="errmsg">{{errmsg}}</div>  
  35.           </div>  
  36.             
  37.           <div class="form-group">  
  38.               <div class="col-md-12 alert alert-success" *ngIf="successmsg">{{successmsg}}</div>  
  39.           </div>  
  40.     
  41.           </form>  
  42.     </div>       
  43.   </div>  
  44.  </div>  
In HTML templete, we are using bootstrap for styling. So, let us install bootstrap now using the below command and import the style.css file.
 
npm install bootstrap@4 --save
  1. /* import  bootstrap in style.css file */  
  2. @import "~bootstrap/dist/css/bootstrap.css" 
Step 10 - Open app.module.ts File
 
Now, open the app.module.ts file. We need to import the service and required modules like Form module, HTTPClient module etc. For that, we can use the following code.
  1. import { BrowserModule } from '@angular/platform-browser';  
  2. import { NgModule } from '@angular/core';  
  3.   
  4. import { AppComponent } from './app.component';  
  5. import { LoginComponent } from './login/login.component';  
  6.  
  7.   
  8. import {FormsModule,ReactiveFormsModule } from '@angular/forms'  
  9. import {MyserviceService} from './myservice.service'  
  10. import { HttpClientModule } from '@angular/common/http';  
  11.   
  12.   
  13.   
  14. @NgModule({  
  15.   declarations: [  
  16.     AppComponent,  
  17.     LoginComponent  
  18.   ],  
  19.   imports: [  
  20.     BrowserModule,  
  21.     FormsModule,  
  22.     ReactiveFormsModule ,  
  23.     HttpClientModule  
  24.   ],  
  25.   providers: [MyserviceService],  
  26.   bootstrap: [AppComponent]  
  27. })  
  28. export class AppModule { }  
Open the app.component.html file and write the given below code for rendering the login HTML templete.
  1. <app-login></app-login>  
We are almost done with the login component, module, and service code.
 
Step 11 - Run Application
 
Now, let us run both the applications - Web API and Agular application.
 
ng serve -o 
 
After compiling successfully, you will see the output like in the below image. The port number here is 4200 that is our Web API application port.
 
 
 
Here, we are receiving a token as a response. We are passing this bearer token with the header in the HTTP request or we can also pass it with HTTP interceptor and validate on the server-side controller level or action level, as you can see in the below code snippet. 
  1. [Authorize]  
  2. public class MyController : ApiController  
  3. {  
  4.    // your code   
  5. }   

Summary

 
I have attached the .rar files of this demonstration. This file does not hold the packages folder, Web API, and node module folder. You can download the source code. For Angular application, use the below command for installing the package.
 
npm install
 
In this article, we learned the implementation of token-based authentication using Web API, Entity Framework, and Angular 7. Thank you for reading this article.


Similar Articles