Web API Token Based Authentication With Angular - Part One

Authentication is a vital process in system programming. Authentication means verifying the user who is accessing the system. Today, we are using modern devices that have different types of apps or software and sometimes, we directly access the website from the browser. To access this application, we probably need to pass our credentials and these systems verify it. If you are a valid user, then it will allow accessing the system otherwise not.

We have available different types of authentication in .NET programming like Windows Authentication, Forms Authentication, Claim Based Authentication, Token Based Authentication etc. Today, we will discuss Token Based Authentication in detail.

What is Token Based Authentication?

Token Based Authentication is not very different from other authentication mechanisms but yes, it is more secure, more reliable, and makes your system loosely coupled. It will be a better choice to create REST APIs using token-based authentication if your API has reached a broad range of devices, like mobiles, tablets, and traditional desktops.

In token based authentication, you pass your credentials [user name and password], which go to the authentication server. The server verifies your credentials and if it is a valid user, then it will return a signed token to the client system, which has an expiration time. The client can store this token for locally using any mechanism like local storage, session storage etc. and if the client makes any other call to the server for data, then it does not need to pass its credentials every time. The client can directly pass the token to the server, which will be validated by the server and if the token is valid, then you will able to access your data.

How to implement

In this demonstration, we will use Web API as a service and Angular JS as a client. So, let me create dummy database “Test” and two tables “Users” and “Employee” respectively. Users table will store the user related information like name, username, and password. Employee table is basically for dummy data. You can use the following SQL script to generate this database and tables.

  2. GO  
  4. USE TEST  
  5. GO  
  7. CREATE TABLE Users(Id INT IDENTITY(1,1) PRIMARY KEYName varchar(255) NOT NULL, UserName varchar(50), Password varchar(50))  
  8. INSERT INTO [TEST].[dbo].[Users](Name, UserName, PasswordVALUES('Mukesh Kumar''Mukesh', AAAAAA');  
  10. CREATE TABLE Employees(Id INT IDENTITY(1,1) PRIMARY KEYName varchar(255) NOT NULL, Address varchar(500))  
  11. INSERT INTO Employees (Name, Address) VALUES('Mukesh Kumar''New Delhi')  
  12. INSERT INTO Employees (Name, Address) VALUES('John Right''England')  
  13. INSERT INTO Employees (Name, Address) VALUES('Chris Roy''France')  
  14. INSERT INTO Employees (Name, Address) VALUES('Anand Mahajan''Canada')  
  15. INSERT INTO Employees (Name, Address) VALUES('Prince Singh''India')  

Move to the next part and create a service that will implement token-based authentication. So, we're going to create a Web API project and for the client application, we will use AngularJS from where we will pass user credentials.

To create Web API project, first, open Visual Studio 2015 and go to File >> New >> Project. It will open New Project window. Select "Web" from Installed Template and then from the right pane, choose “ASP.NET Web Application”. Provide the name like “EmployeeService” and click OK.

The next window will provide you options to choose web application template. Here, you need to choose Web API with No Authentication and click OK. Therefore, your application is ready to run.

Before moving on, to implement token-based authentication, we have to add fthe ollowing packages as a references from NuGet Package Manager. So, just right click on references in solution and select Manage NuGet Packages. It will open NuGet Package Manager Windows; you can search these packages one by one from search box in Browse tab. Once these packages are able to find out in NuGet click to install; After Installation, these packages will be available in references.

  • Microsoft.Owin
  • Microsoft.Owin.Host.SystemWeb
  • Microsoft.Owin.Security.OAuth
  • Microsoft.Owin.Security
  • Microsoft.AspNet.Identity.Owin

In this demonstration, we will not use Global.asax file. So, first, delete the Global.asax from solution and add new class “Startup.cs” at the same location of Global.asax file and add following code.

  1. using EmployeeService.Provider;  
  2. using Microsoft.Owin;  
  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;  
  11. [assembly: OwinStartup(typeof(EmployeeService.Startup))]  
  12. namespace EmployeeService  
  13. {  
  14.     public class Startup  
  15.     {  
  16.         public void ConfigureAuth(IAppBuilder app)  
  17.         {  
  19.             var OAuthOptions = new OAuthAuthorizationServerOptions  
  20.             {  
  21.                 AllowInsecureHttp = true,  
  22.                 TokenEndpointPath = new PathString("/token"),  
  23.                 AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(20),  
  24.                 Provider = new SimpleAuthorizationServerProvider()  
  25.             };  
  27.             app.UseOAuthBearerTokens(OAuthOptions);  
  28.             app.UseOAuthAuthorizationServer(OAuthOptions);  
  29.             app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());  
  31.             HttpConfiguration config = new HttpConfiguration();  
  32.             WebApiConfig.Register(config);  
  33.         }  
  35.         public void Configuration(IAppBuilder app)  
  36.         {  
  37.             ConfigureAuth(app);  
  38.             GlobalConfiguration.Configure(WebApiConfig.Register);  
  39.         }  
  40.     }  
  41. }   

In the above code, you can see, we are using OWIN [Open Web Interface for .Net] that is an interface between your web server and web application. So, it works as a middleware in applications, which process your incoming request and validate it. Here we are using SimpleAuthorizationServerProvider, which is nothing but a class which validate user based on their credentials. You can find this class code at the last.

Now it’s time to create a model where we can perform database operations like fetching the user information based on credentials and employee data. We can use different ways here to get data like Repository pattern with Unit of work or Dapper. But we want to make this example simple and keep the main focus on Token Based Authentication only. So, right click on solution and Click to add and then New Item and choose Ado.Net Entity Model.


Next window will provide you several options to connect your code with database. Here, we are selecting the first one, "EF Designer from database". It will create POCO classes for database's tables.


In the next window, you need to choose New Connection and it provides all the details to access your database. Once you will be provided all details, just click on Test Connection to check if everything is correct and move to Next.



Once your connection is created with database, you will find all your database components like tables, views and SPs. So, here you just need to select only Tables and click to finish.


Once you click to finish, it will generate all database components as model in EmployeeModel.edmx file like  the following image.


Now it’s time to create a new controller to get employee data; so, you will need to add new controller as EmployeeController and add following code.

  1. using System.Collections.Generic;  
  2. using System.Linq;  
  3. using System.Web.Http;  
  5. namespace EmployeeService.Controllers  
  6. {  
  7.     public class EmployeeController : ApiController  
  8.     {  
  9.         [HttpGet]  
  10.         [Authorize]  
  11.         public List<Employee> GetEmployees()  
  12.         {  
  13.             using (var db = new TESTEntities())  
  14.             {  
  15.                 var employees = db.Employees.ToList();  
  16.                 return employees;  
  17.             }  
  18.         }  
  19.     }  
  20. }  

As we discussed above, to validate user, we are using "SimpleAuthorizationServerProvider" class which inherits from OAuthAuthorizationServerProver. Here we are overriding two methods. First one is ValidateClientAuthentication, which will validate the request. And second one is  GrantResourceOwnerCredentials, which will grant to access application based on your credentials. So, basically in this method, we are validating to user. So, it validates every request and verifies your credentials and returns the token.

  1. using Microsoft.Owin.Security;  
  2. using Microsoft.Owin.Security.OAuth;  
  3. using System.Collections.Generic;  
  4. using System.Linq;  
  5. using System.Security.Claims;  
  6. using System.Threading.Tasks;  
  7. using System.Web.Http.Cors;  
  9. namespace EmployeeService.Provider  
  10. {  
  11.     [EnableCors(origins: "*", headers: "*", methods: "*")]  
  12.     public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider  
  13.     {  
  14.         public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)  
  15.         {  
  16.             context.Validated(); //   
  17.         }  
  19.         public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)  
  20.         {  
  21.             var identity = new ClaimsIdentity(context.Options.AuthenticationType);  
  22.             context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin"new[] { "*" });  
  24.             using (var db = new TESTEntities())  
  25.             {  
  26.                 if (db != null)  
  27.                 {  
  28.                     var empl = db.Employees.ToList();  
  29.                     var user = db.Users.ToList();  
  30.                     if (user != null)  
  31.                     {  
  32.                         if (!string.IsNullOrEmpty(user.Where(u => u.UserName == context.UserName && u.Password == context.Password).FirstOrDefault().Name))  
  33.                         {  
  34.                             identity.AddClaim(new Claim("Age""16"));  
  36.                             var props = new AuthenticationProperties(new Dictionary<string, string>  
  37.                             {  
  38.                                 {  
  39.                                     "userdisplayname", context.UserName  
  40.                                 },  
  41.                                 {  
  42.                                      "role""admin"  
  43.                                 }  
  44.                              });  
  46.                             var ticket = new AuthenticationTicket(identity, props);  
  47.                             context.Validated(ticket);  
  48.                         }  
  49.                         else  
  50.                         {  
  51.                             context.SetError("invalid_grant""Provided username and password is incorrect");  
  52.                             context.Rejected();  
  53.                         }  
  54.                     }  
  55.                 }  
  56.                 else  
  57.                 {  
  58.                     context.SetError("invalid_grant""Provided username and password is incorrect");  
  59.                     context.Rejected();  
  60.                 }  
  61.                 return;  
  62.             }  
  63.         }  
  64.     }  
  65. }  

At the end, you just need to Enable CORS in WebAPIConfig file.

  1. using Newtonsoft.Json.Serialization;  
  2. using System.Linq;  
  3. using System.Net.Http.Formatting;  
  4. using System.Web.Http;  
  5. using System.Web.Http.Cors;  
  7. namespace EmployeeService  
  8. {  
  9.     public class WebApiConfig  
  10.     {  
  11.         public static void Register(HttpConfiguration config)  
  12.         {  
  13.             // Web API configuration and services  
  15.             EnableCorsAttribute cors = new EnableCorsAttribute("*""*""*");  
  16.             config.EnableCors(cors);  
  18.             // Web API routes  
  19.             config.MapHttpAttributeRoutes();  
  21.             config.Routes.MapHttpRoute(  
  22.                 name: "DefaultApi",  
  23.                 routeTemplate: "api/{controller}/{id}",  
  24.                 defaults: new { id = RouteParameter.Optional }  
  25.             );  
  27.             var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();  
  28.             jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();  
  29.         }  
  30.     }  
  31. }   

So, everything is setup and looks good. Let's move to test our service. To test this open PostMan Chrome Extension and choose GET method and provide the API URL and click to Send. You can see with below image that your request has been denied by the server.


Now, it’s time to validate user first and get the token. And this token will be passed with next call in the header. So, select the method as POST and pass TOKEN URL as following image shows and provide your credentials. For me, username ="Mukesh" and password="*******". Don't forget to mention grant_type as password. If everything will be set up, click to send button. 

Once server validates your credentials it will correct then it will return an access_token with expiry time as following.


Now you need to call same API call as we have called earlier but this time you will need to pass your token in Headers using "Authorization" key. Token should be passed followed by "bearer yourtoken". Now you can see that we are able to get the employee data. It is because we are a valid user.



So, we have seen how to implement Token Based Authentication in Web API and in the next part we will see how to use this token in angular js applications.

I hope this post helps you. Please put your feedback using comments which will help me improve for the next post. If you have any doubts, please ask your doubts or query in the comments section.