Token Based Authentication in ASP.NET Web API

Token-Based Authentication in ASP.NET Web API

In this article, I will discuss how to implement Token Based Authentication in ASP.NET Web API to secure the server resources with an example. Please read our previous article, where we discussed implementing a Client-Side HTTP Message Handler with some examples. As part of this article, we will discuss the following pointers.

  1. Why do we need Token Based Authentication in Web API?
  2. Advantages of using Token-Based Authentication.
  3. How does the Token-Based Authentication work?
  4. Implementing Token-Based Authentication in ASP.NET Web API.
  5. Testing the Token Authentication using Postman.
Why Do We Need Token Based Authentication in ASP.NET Web API?

The ASP.NET Web API is an ideal framework Microsoft provides to build Web APIs, i.e., HTTP-based services on top of the .NET Framework. Once we develop the services using Web API, then these services are going to be consumed by a broad range of clients, such as

  1. Browsers
  2. Mobile applications
  3. Desktop applications
  4. IOTs, etc.

Nowadays, the use of WEB API is increasing rapidly. So, as developers, we should know how to develop Web APIs. Only developing Web APIs is not enough if there is no security. So, it is also extremely important for us as a developer to implement security for all types of clients (such as Browsers, Mobile Devices, Desktop applications, and IoTs) who will use our Web API services.

The most preferred approach nowadays to secure the Web API resources is by authenticating the users in the Web API server by using the Signed Token (which contains enough information to identify a particular user), which must be sent to the server by the client with every request. This is called the Token-Based Authentication approach.

How Does The Token-Based Authentication work?

To understand how token-based authentication works, please look at the following diagram.

How does the Token-Based Authentication work

The Token-Based Authentication works as Follows:

  1. The user enters his credentials (i.e., the username and password) into the client (here, the client means the browser or mobile devices, etc).
  2. The client then sends these credentials (i.e., username and password) to the Authorization Server.
  3. Then, the Authorization Server authenticates the client credentials (i.e., username and password) and generates and returns an access token. This Access Token contains enough information to identify a user and also contains the token expiry time.
  4. The client application then includes the Access Token in the Authorization header of the HTTP request to access the restricted resources from the Resource Server until the token is expired.

Let’s discuss the step-by-step procedure to implement Token-Based Authentication in ASP.NET Web API. Then, we will also see how to use Token Based Authentication to access restricted resources using the client tools Postman and Fiddler.

Step 1: Creating the Required Database

We are going to use the following UserMaster table in this demo.

Token Based Authentication in Web API

Please use the script below to create and populate the UserMaster table with the required sample data.

CREATE DATABASE SECURITY_DB
GO

USE [SECURITY_DB]

CREATE TABLE UserMaster
(
  UserID INT PRIMARY KEY,
  UserName VARCHAR(50),
  UserPassword VARCHAR(50),
  UserRoles VARCHAR(500),
  UserEmailID VARCHAR(100),
)
GO

INSERT INTO UserMaster VALUES(101, 'Anurag', '123456', 'Admin', 'Anurag@g.com')
INSERT INTO UserMaster VALUES(102, 'Priyanka', 'abcdef', 'User', 'Priyanka@g.com')
INSERT INTO UserMaster VALUES(103, 'Sambit', '123pqr', 'SuperAdmin', 'Sambit@g.com')
INSERT INTO UserMaster VALUES(104, 'Pranaya', 'abc123', 'Admin, User', 'Pranaya@g.com')
GO
Step 2: Create an Empty ASP.NET Web API Project with the name TokenAuthenticationWEBAPI

Go to the File menu > create > project > here select ASP.NET Web Application (.NET Framework) under web. Provide the application name as TokenAuthenticationWEBAPI and select the project location where you want to create the project. Then click on the OK button as shown in the below image.

Creating an empty Web API Project with the name TokenAuthenticationWEBAPI

Once you click the OK button, a new window will open with Name New ASP.NET Web Application for selecting the Project Templates. From this window, you need to select the Empty project template, as we will do everything from scratch, and then check the MVC and Web API checkbox from the Add folder and core references for and click on the OK button as shown in the below image. Please make sure to select No Authentication, as we are going to implement Token Based Authentication from Scratch.

ASP.NET Web API Token Based Authentication

Step 3: Add the Required References from NuGet packages into Your Application.

To Implement the Token-Based Authentication in ASP.NET Web API, we must install the following references from NuGet packages. In the later part of this article, we will discuss the use of each package below.

  1. Microsoft.Owin.Host.SystemWeb
  2. Microsoft.Owin.Security.OAuth
  3. Microsoft.Owin.Cors
  4. Newtonsoft.json

To add the above references from NuGet, Go to Solution Explorer > Right Click on the References > Click on Manage NuGet Packages > Search for Microsoft.Owin.Host.SystemWeb,  Microsoft.Owin.Security.OAuth, Microsoft.Owin.Cors and Newtonsoft.json and install. 

Note: The dependency references are automatically installed into your application when you install the above packages.

Step 4: Creating the ADO.NET Entity Data Model

Here, we will use the DB First Approach of Entity Framework to create the Entity Data Model against the SECURITY_DB database, which we have already created in Step 1, and then select the UserMaster table from the SECURITY_DB database.

Step 5: Create a Repository Class

We need to create a class with the name UserMasterRepository, which will validate the user and return the user information. Copy and paste the following code once you create the UserMasterRepository.cs class file. As you can see in the below code, the ValidateUser method takes the username and password as input parameters and then validates this. If the username and password are valid, then it will return the UserMaster object; otherwise, it will return null. Later, we will discuss when and where we will use this method.

namespace TokenAuthenticationInWebAPI.Models
{
    public class UserMasterRepository : IDisposable
    {
        // SECURITY_DBEntities it is your context class
        SECURITY_DBEntities context = new SECURITY_DBEntities();

        //This method is used to check and validate the user credentials
        public UserMaster ValidateUser(string username, string password)
        {
            return context.UserMasters.FirstOrDefault(user =>
            user.UserName.Equals(username, StringComparison.OrdinalIgnoreCase)
            && user.UserPassword == password);
        }

        public void Dispose()
        {
            context.Dispose();
        }
    }
}

Step 6: Add a class for Validating the User Credentials Asking for Tokens.

We need to add a class file named MyAuthorizationServerProvider.cs to our application. Within that class, we must write the logic for validating the user credentials and generating the access token. The Authorization Server will use this class to Validate the Client Credentials. 

We need to inherit the MyAuthorizationServerProvider class from OAuthAuthorizationServerProvider class and then need to override the ValidateClientAuthentication and GrantResourceOwnerCredentials method. So, before proceeding and overriding these two methods, let us first understand what exactly these methods are going to perform.

ValidateClientAuthentication Method:

The ValidateClientAuthentication method is used for validating the client application. For the sake of simplicity, we will discuss what a client is and how to validate a client in more detail in the next article.

GrantResourceOwnerCredentials Method:

The GrantResourceOwnerCredentials method is used to validate the client credentials (i.e., username and password). It only generates the access token if the credentials are valid. The client, then using this access token, can access the authorized resources from the Resource Server.

As we already discussed, the Signed Access Token contains enough information to identify a user. Now, the question is how. Let’s discuss this in detail.

First, we need to create an instance of the ClaimsIdentity class, and to the constructor of the ClaimsIdentity class, we need to pass the Authentication Type. The Authentication Type is a bearer token, as we will use Token-Based Authentication. 

Once we create the ClaimsIdentity instance, we need to add the claims, such as Role, Name, Email, etc, to the ClaimsIdentity instance. The user information will be included in the Signed Access Token. You can add any number of claims; once you add more, the token size will increase. So, it is not recommended to include all the information in the claim; whichever information is required, include only that information.

MyAuthorizationServerProvider

Create a class file named MyAuthorizationServerProvider.cs and copy and paste the following code.

using Microsoft.Owin.Security.OAuth;
using System.Security.Claims;
using System.Threading.Tasks;

namespace TokenAuthenticationInWebAPI.Models
{
    public class MyAuthorizationServerProvider : OAuthAuthorizationServerProvider
    {
        public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated();
        }

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            using (UserMasterRepository _repo = new UserMasterRepository())
            {
                var user = _repo.ValidateUser(context.UserName, context.Password);
                if (user == null)
                {
                    context.SetError("invalid_grant", "Provided username and password is incorrect");
                    return;
                }
                var identity = new ClaimsIdentity(context.Options.AuthenticationType);
                identity.AddClaim(new Claim(ClaimTypes.Role, user.UserRoles));
                identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
                identity.AddClaim(new Claim("Email", user.UserEmailID));

                context.Validated(identity);
            }
        }
    }
}
Step 7: Add the OWINStartup Class.

In the context of ASP.NET Web API, the OWINStartup class is used to specify the configuration for the OWIN (Open Web Interface for .NET) pipeline, which can be used for running web applications. When your Web API application starts, the OWINStartup class configures middleware components in the OWIN pipeline. It defines the order and configuration of middleware components that handle incoming HTTP requests and responses. Here’s how it works:

Here’s a brief explanation of the terms involved:

  • OWIN: OWIN defines a standard interface between .NET web servers and web applications. It’s aimed at decoupling the web server from the application logic, making creating middleware for .NET web development easier.
  • Startup Class: This class is where you configure all the OWIN middleware components you want to use in your application. The class must be defined in your assembly with the OwinStartup attribute, which tells the OWIN host that this class should be used to configure the application.

Here’s what each part of the OWINStartup class typically does:

  • Configuration Method: This is the entry point for configuring middleware in your HTTP pipeline. It’s where you can configure authentication, Web API routes, enable CORS, etc.
  • IAppBuilder: This interface is provided by OWIN and allows you to build the components that will handle requests in your web application.

We need to add the OWINStartup class, where we will configure the OAuth Authorization Server. This is going to be our authorization server. To do so, go to the Solution Explorer > Right Click on Project Name from the Solution Explorer > Add > New Item > Select OWIN Startup class > Enter the class name as Startup.cs > and then click on the Add button as shown in the below image.

Token Based Authentication in ASP.NET Web API

Once you created the Owin Startup class, please copy and paste the code below.

using System;
using Microsoft.Owin;
using Owin;
using TokenAuthenticationInWebAPI.Models;
using Microsoft.Owin.Security.OAuth;
using System.Web.Http;

[assembly: OwinStartup(typeof(TokenAuthenticationInWebAPI.App_Start.Startup))]

namespace TokenAuthenticationInWebAPI.App_Start
{
    // In this class we will Configure the OAuth Authorization Server.
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // Enable CORS (cross origin resource sharing) for making request using browser from different domains
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            
            OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions
            {
                AllowInsecureHttp = true,

                //The Path For generating the Toekn
                TokenEndpointPath = new PathString("/token"),

                //Setting the Token Expired Time (24 hours)
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),

                //MyAuthorizationServerProvider class will validate the user credentials
                Provider = new MyAuthorizationServerProvider()
            };

            //Token Generations
            app.UseOAuthAuthorizationServer(options);
            app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
            
            HttpConfiguration config = new HttpConfiguration();
            WebApiConfig.Register(config);
        }
    }
}
Understanding the OwinStartup Class Code:

Here, we created a new instance of the OAuthAuthorizationServerOptions class and then set its options as follows:

  1. Here, we set the path for generating the tokens as http://localhost:portnumber/token. Later, we will see how to issue an HTTP Post request to this endpoint to generate the access token.
  2. We have specified the expiry time for the access token as 24 hours. So if the user tries to use the same access token after 24 hours from the issue time, then this request will be rejected, and HTTP status code 401 will be returned.
  3. We also specified the implementation on how to validate the client credentials for users asking for the access tokens in the custom class named MyAuthorizationServerProvider.

Finally, we passed the options to the extension method UseOAuthAuthorizationServer, which will add the authentication middleware to the Request Processing Pipeline.

Step 8: Add a Web API Controller. 

Now, we need to create Web API resources. To do so, add an empty Web API Controller, where we will add some action methods to check whether the Token-Based Authentication is working fine or not.

Go to Solution Explorer > Right-click on the Controllers folder > Add > Controller > Select WEB API 2 Controller – Empty > Click on the Add button. > Enter the controller name as TestController.cs. Finally, click on the Add button to create the TestController. Once you created the TestController, then copy and paste the following code.

using System.Linq;
using System.Security.Claims;
using System.Web.Http;

namespace TokenAuthenticationInWebAPI.Controllers
{
    public class TestController : ApiController
    {
        //This resource is For all types of role
        [Authorize(Roles = "SuperAdmin, Admin, User")]
        [HttpGet]
        [Route("api/test/resource1")]
        public IHttpActionResult GetResource1()
        {
            var identity = (ClaimsIdentity)User.Identity;
            return Ok("Hello: " + identity.Name);
        }

        //This resource is only For Admin and SuperAdmin role
        [Authorize(Roles = "SuperAdmin, Admin")]
        [HttpGet]
        [Route("api/test/resource2")]
        public IHttpActionResult GetResource2()
        {
            var identity = (ClaimsIdentity)User.Identity;            
            var Email = identity.Claims
                      .FirstOrDefault(c => c.Type == "Email").Value;

            var UserName = identity.Name;
            
            return Ok("Hello " + UserName + ", Your Email ID is :" + Email);
        }

        //This resource is only For SuperAdmin role
        [Authorize(Roles = "SuperAdmin")]
        [HttpGet]
        [Route("api/test/resource3")]
        public IHttpActionResult GetResource3()
        {
            var identity = (ClaimsIdentity)User.Identity;
            var roles = identity.Claims
                        .Where(c => c.Type == ClaimTypes.Role)
                        .Select(c => c.Value);
            return Ok("Hello " + identity.Name + "Your Role(s) are: " + string.Join(",", roles.ToList()));
        }
    }
}

Here, in the above controller, we have created three resources as follows,

  1. /api/test/resource1 This resource can be accessed by all three types of roles such as Admin, SuperAdmin, and User
  2. /api/test/resource2This resource can be accessed by the users who are having the roles Admin and SuperAdmin
  3. /api/test/resource3This resource can be accessed only by the users who have the role of SuperAdmin

To test this, we will use a client tool called Postman. First, you need to run your Web API application. If you are new to Postman, please read the following, where we discussed using Postman to test Web API rest services.

How to use Postman to test Rest Services?

Step9: Testing the Token Authentication

Test 1: Without Access Token, try to make a request for the following URI

http://localhost:xxxxx/api/test/resource1

You need to change the port number. You must provide the port number where your Web API application runs.

Securing Web API Resouces Using Token-Based Authentication

As expected, you got 401 unauthorized responses

Test 2: Try to Create the Access Token with Invalid Credentials

As we don’t have any user with the name test, let’s try to create the Access Token for the test user. Select the method type as POST (1), enter the URL as http://localhost:PortNumber/token (2), and then click on the body tab (3) and then select x-www-form-urlencoded (4) and then enter 3 parameters (5)

  1. username (value : test)
  2. password (value: test)
  3. grant_type (value: password)

And then click on the Send button (6).

Securing Web API Resouces Using Token-Based Authentication

Once you click on the send button, you will get the status 400 Bad Request, as expected, and it also tells that in the error description the provided username and password are incorrect. Let’s generate the access token with valid credentials for the user Anurag, whose password is 123456, as shown in the below image.

Authentication in Web API

As you can see, when you click the Send button, you will get the status code 200 OK. Along with you will also get the access token, which contains enough information to identify the user Anurag. You can also see in the Response section that the token type is Bearer, and the token expires time in seconds.

Test 3: Access Restricted Resources with the Access Token.

/api/test/resource2

First, copy the access token that we just generated in the previous example, and we will use the token as shown below.

Authorization: Bearer Access_Token(value)

Authentication in Web API

You can see that when you click on the Send button, you will get 200 Ok as expected because the resource /api/test/resource2 has been accessed by the Roles Admin and SuperAdmin and here, the user Anurag has the Role Admin, so, we get the above response.

But the above user cannot access the resource /api/test/resource3 because the resource3 can only be accessed by the user whose role is SuperAdmin. Let’s prove this.

Web API Token-Based Authentication

As you can see, the response is 401 unauthorized. But you can access this resource if you generate the token for the user whose Role is SuperAdmin.

Let’s have a look at the MyAuthorizationServiceProvider class.

Web API Token-Based Authentication

The first method, i.e., the ValidateClientAuthentication method, validates the Client. In this example, we assume that we have only one client, so we’ll always return that it is validated successfully. But in real time, you may have multiple clients, and you need to validate the clients. So, in the next article, we will discuss how to use the ValidateClientAuthentication method to validate the client.

In the next article, I will discuss Client Validation Using Basic Authentication in Web API with an example. I explain how to implement Token Based Authentication in Web API in this article with an example. I hope you enjoy this article. 

45 thoughts on “Token Based Authentication in ASP.NET Web API”

  1. Thanks a lot Sir,
    This article is great and i am very much happy to recommend this to my friends . Such complex thing has been explained in such simple words. I wish my best wishes to the team and it has been great learning experience.
    Please keep growing this website.

    With Regards,
    Abhishek Singh

  2. Thank you very much, but i think there is a small issue must be solved in the code above because i faced error with authorized by roles if i have more than one roles for the user
    so i modified the code at that section to be :

    foreach (var item in user.Roles.Split(‘,’))
    {
    identity.AddClaim(new Claim(ClaimTypes.Role, item.Trim()));
    }

    hope this will solve the issue at above code for the best practice to programmers

    Many thanks for you
    Best Regards

  3. Basic Question though..One of the main disadvantage with Basic authentication is Credentials are sent as plain text in each and every request. However in token authentication also, we sending the very first request in plain text.

    1. SECURITY_DBEntities is the context class name. While interacting with database using entity framework you need to provide the context as SECURITY_DBEntities.

  4. i have sender where token based system applied
    means admin give you token
    we will add it in the sender script where token.txt
    sender will work..!!

    i want to know how to create that types of token
    and we can use this method and second it will work on localhost

  5. When I run the API using Visual Studio 2019 by pressing F5 on the keyboard, I always get an error stating 404 not found.
    Am I missing anything here?

  6. i get errors when i add these to configure method on startup

    app.UseOAuthAuthorizationServer(options);
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    HttpConfiguration config =new HttpConfiguration() ;
    WebApiConfig.Register();

    the error is :

    ‘IApplicationBuilder’ does not contain a definition for ‘UseOAuthAuthorizationServer’ and the best extension method overload ‘OAuthAuthorizationServerExtensions.UseOAuthAuthorizationServer(IAppBuilder, OAuthAuthorizationServerOptions)’ requires a receiver of type ‘IAppBuilder’

    1. I was having the same issue and what the problem was for me is that I was using IApplicationBuilder vs IAppBuilder. I am trying to integrate the both but I am not sure yet. Hope this points you in the right direction. Good Luck!

  7. public void Configure(IApplicationBuilder app, IHostingEnvironment env, mydbContext db, IAppBuilder ap)
    {

    if (env.IsDevelopment())
    {
    app.UseDeveloperExceptionPage();
    }
    else
    {
    app.UseExceptionHandler(“/Error”);
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseSpaStaticFiles();

    app.UseMvc(routes =>
    {
    routes.MapRoute(
    name: “default”,
    template: “{controller}/{action=Index}/{id?}”);
    });

    app.UseSpa(spa =>
    {
    // To learn more about options for serving an Angular SPA from ASP.NET Core,
    // see https://go.microsoft.com/fwlink/?linkid=864501

    spa.Options.SourcePath = “AppFrontEnd”;

    if (env.IsDevelopment())
    {
    //spa.UseAngularCliServer(npmScript: “start”);
    spa.UseProxyToSpaDevelopmentServer(“http://localhost:4200”);
    }
    });

    // Enable CORS (cross origin resource sharing) for making request using browser from different domains
    ap.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);

    OAuthAuthorizationServerOptions options = new OAuthAuthorizationServerOptions
    {
    AllowInsecureHttp = true,
    //The Path For generating the Toekn
    TokenEndpointPath = new PathString(“/token”),
    //Setting the Token Expired Time ()
    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(5),
    //MyAuthorizationServerProvider class will validate the user credentials
    Provider = new MyAuthorizationServerProvider()
    };
    //Token Generations
    ap.UseOAuthAuthorizationServer(options);
    ap.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    WebApiConfig.Register(new HttpConfiguration());

    }

    when i add these the above errors was desapear but is that true ?
    but get error in these line
    WebApiConfig.Register(new HttpConfiguration());
    im using dotnetcore 2.2 by dotnet angular project

  8. As far as I saw you didn’t say anything about packages and why you used them. Why we have to use them? What happens if we don’t use it?

      1. @LAWRAOKE ,
        I faced this… then solved by using Key: grant_type and Value: password
        value is case sensitive i guess, so it must be “password” though your password filed can be like PassWord. 🙂

  9. Its very interesting explanatory,
    clean!
    i’m facing some error 400 when i’m trying to use angular 9, but with postman its responding positive.
    can you help?

  10. Luciano Dal Monte

    Dears,
    starting from this great and very well explained example and the others of your beatiful site I was able to implement some robust webapis that use token authentication: really, I have to thank you a lot for this.
    Now, I should implement a new webapi to put together an existent web project asp.net core razor pages that uses Asp.net identity and the object SignInManager of Asp.Net Core to verify user identity. Is it possible to re-implement your example above together with Asp.net Identity and SignInManager object to get the user identity, verify it and if correct get the token?
    Lucius

  11. Thank you!
    Interesting this tutorial.
    The question I ask myself is:
    Where is the secret to sign the token sent by the user

    1. Hi.. there is no secret key here since, the token generation is happening by calling the oauth API, that will sign the token using it’s own secret key and send the token. In case you use your own login to create a JWT token, you would require to sign it using secret key.

  12. always getting error ( “Message”: “Authorization has been denied for this request.”), even when I pass the valid token.
    Can any body please help?

  13. Good Article. Can you please also explain the concept of JWT and JWT Refresh Tokens? it will be more helpful and updated. JWT is more common now.

  14. Prabodh Jadhav

    Apologies if my question is lame. But can someone copy the access token from the browser and use it for some other request ?

  15. The Microsoft.Owin.* NuGet packages are only compatible with .NET Standard, not .NET Core. Is there a .NET Core equivalent?

Leave a Reply

Your email address will not be published. Required fields are marked *