Token Based Authentication in ASP.NET Web API

13 Jan 2024
Advanced
288K Views
14 min read  

Token-Based Authentication in ASP.NET Web API: An Overview

In a Web API Tutorial, token-based authentication involves a client application sending credentials to the server (usually a username and password) in exchange for a unique token. This token acts as proof of identity for subsequent requests, removing the need to provide sensitive credentials repeatedly, making it a valuable concept to learn in ASP.NET Core Training.

Why Do We Need Token-Based Authentication in ASP.NET Web API?

The ASP.NET Web API is an excellent framework provided by Microsoft for developing Web APIs, i.e., HTTP-based services on top of the .NET Framework. Once we have developed the services using Web API, they will be used by a wide range of customers, including

  • Browsers
  • Mobile applications
  • Desktop applications
  • IOTs, etc.

How Does The Token-Based Authentication work?

 Token-Based Authentication

Token-Based Authentication operates as follows:

  • The user inserts his credentials (i.e., username and password) into the client (here, the client refers to the browser or mobile device, for example).
  • After that, the client sends these credentials (username and password) to the Authorization Server.
  • After that, the Authorization Server validates the client credentials (username and password) and generates and returns an access token. This Access Token contains sufficient information to identify a user and the token expiry time.
  • The Access Token is then included in the Authorization header of the HTTP request by the client application toaccess the restricted resources from the Resource Server until the token expires.

Implementation of Token-Based Authentication

Step 1

Open Visual Studio 2017 => create a new Web API project => Name the project, in my case, I named it Token_Auth_Web_API, and set the Authentication to an Individual User Account as shown in the below figure.

Step 2

Go to Startup.cs file under the App_Start folder in the solution

// Configure the application for OAuth based flow
 PublicClientId = "self";
 OAuthOptions = new OAuthAuthorizationServerOptions
 {
 TokenEndpointPath = new PathString("/Token"),
 Provider = new ApplicationOAuthProvider(PublicClientId),
 AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
 AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
 // In production mode set AllowInsecureHttp = false
 AllowInsecureHttp = true
 }; 

Install the Owin using the below command in the package manager console

Install-Package Owin -Version 1.0.0

Owin: open web interface for .NET is a middleware that defines the interface between the web server and application.

TokenEndPointPath: This is a kind of request path client applications that communicate with the server directly as part of the OAuth protocol. It must begin with a slash “/”

  1. Provider: The object provided by the application to process the event raised by the authorization server middleware.

  2. AuthorizeEndpointPath: The request path where the client application will redirect the client/user to obtain a user account to issue a token

  3. AccessTokenExpireTimeSpan: Defines the validity of the token

  4. AllowInsecureHttp: It will allow a normal http request to authorize, if it is set to false, it will process only HTTP requests.

Step 3

To register the user, we are going to use the api/Account/Register Endpoint from a client which is available in AccountController of our WEB API project, as shown below.

 
// POST api/Account/Register
 [AllowAnonymous]
 public async Task<IHttpActionResult> Register(RegisterBindingModel model)
 {
 if (!ModelState.IsValid)
 {
 return BadRequest(ModelState);
 }

 var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };

 IdentityResult result = await UserManager.CreateAsync(user, model.Password);

 if (!result.Succeeded)
 {
 return GetErrorResult(result);
 }

 return Ok();
 }

Go to the Index View of the home controller, as shown below figure, and add the code

Home=> Index.cshtml
 
 <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
 <h4> Registration Form</h4>
 <div id="loginDiv" style="width:50%">
 <div style="width:50%">
 <div class="form-group">
 <label for="txtEmail">First Name </label>
 <input type='email' name="email" id="txtEmail" class="form-control">
 </div>
 <div class="form-group">
 <label>Password</label>
 <input type="password" id="textPwd" class="form-control">
 </div>
 <div class="form-group">
 <label>Confrim Password</label>
 <input type="password" id="txtConfirmPwd" class="form-control">
 </div>
 </div>
 <button id="register" class="btn btn-default">Submit</button>
 </div>
 <h4>Login </h4>
 
 <div id="loginDiv" style="width:50%">
 <div class="form-group">
 <label for="txtEmail">First Name </label>
 <input type='email' name="email" id="loginEmail" class="form-control">
 </div>
 <div class="form-group">
 <label>Password</label>
 <input type="password" id="loginPwd" class="form-control">
 </div>
 <button id="btnLogin" class="btn btn-default">Submit</button>
 </div>
 <div>
 <label id="msg"></label>
 </div>
 <script>
 $(document).ready(function () {
 $("#register").on('click', function () {
 var data = { Email: $("#txtEmail").val().trim(), Password: $("#textPwd").val().trim(), ConfirmPassword: $("#txtConfirmPwd").val().trim() };
 $.ajax({
 url: "http://localhost:49501/api/Account/Register",
 type: 'POST',
 data: data,
 success: function (resp) {
 window.location.href = '/Home/Index';
 }
 })
 });
 
 $("#btnLogin").on('click', function () {
 //var data = { Email: $("#loginEmail").val().trim(), Password: $("#textPwd").val().trim(), ConfirmPassword: $("#loginPwd").val().trim() };
 $.ajax(
 {
 url: "/TOKEN",
 type: "POST",
 data: $.param({ grant_type: 'password', username: $("#loginEmail").val(), password: $("#loginPwd").val() }),
 headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
 success: function (resp) {
 sessionStorage.setItem('userName', resp.userName);
 sessionStorage.setItem('accessToken', resp.access_token);
 var authHeaders = {};
 authHeaders.Authorization = 'Bearer ' + resp.access_token;
 $.ajax({
 url: "http://localhost:49501/api/values",
 type: "GET",
 headers: authHeaders,
 success: function (response) {
 $("#loginEmail").val("");
 $("#loginPwd").val("");
 $("#msg").text(response);
 }
 });
 
 },
 error: function () {
 $("#msg").text("Authentication failed");
 }
 })
 });
 
 
 })
 </script>
 

From the above HTML code, it is obvious we have two form

  • Registration Form

  • Login Form

Registration Form: The registration formused to register the user using the /api/Account/Register API Service which doesn’t require any authentication

Login Form: In this user requests to give their credential, once they submit the form /TOKEN post service is fired, once the service validates the user it will generate an access token and send it as a response to a server with a username as shown in below figure.

In Login Ajax call success, we are saving the token and user details, and making another API call /api/values, this function definition is decorated with the [Authorize] attribute. we need to pass the access token as an authorization header whenever this HTTP service request happens from the client side.

 // GET api/values
 [EnableCors(origins: "*", headers: "*", methods: "*", exposedHeaders: "X-My-Header")]
 [Authorize]
 public IEnumerable<string> Get()
 {
 return new string[] {"You are successfully Authenticated to Access the Service"};
 }

[EnableCors(origins: "*", headers: "*", methods: "*", exposedHeaders: "X-My-Header")]: Enabled the CROS origin, so that it can be accessed from any domain

[Authorize]: It is used to authenticate the token sent from the client side, once the authentication is successfully the Get() will be fired

Client-side HTTP request with Authorization Header

$("#btnLogin").on('click', function () {
 $.ajax(
 {
 url: "/TOKEN",
 type: "POST",
 data: $.param({ grant_type: 'password', username: $("#loginEmail").val(), password: $("#loginPwd").val() }),
 headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
 success: function (resp) {
 sessionStorage.setItem('userName', resp.userName);
 sessionStorage.setItem('accessToken', resp.access_token);
 var authHeaders = {};
 authHeaders.Authorization = 'Bearer ' + resp.access_token;
 $.ajax({
 url: "http://localhost:49501/api/values",
 type: "GET",
 headers: authHeaders,
 success: function (response) {
 $("#loginEmail").val("");
 $("#loginPwd").val("");
 $("#msg").text(response);
 }
 });

 },
 error: function () {
 $("#msg").text("Authentication failed");
 }
 })

authHeaders.Authorization = 'Bearer ' + resp.access_token: We are defining the authorization header with the access token when the /api/values HTTP call happens. On the server side, the token is validated, once its success it will return a message “You are successfully Authenticated to Access the Service”

Note: we need to send grant_type: 'password' as the data along with the user name and password through the body of the HTTP request which accesses the URL /TOKEN

Client-side HTTP request

Header with /api/values HTTP call

Success

From the above figures, it is obvious the token is validated, and the service returns a message.

Invalid Credential Entry

If the credential is wrong the service /TOKEN will return the error message which is shown above

Advantages of using Token-Based Authentication in ASP.NET Web API

  1. Server Scalability: The token provided by the client to the server is self-contained, which means it contains enough data to identify the person required for authentication. As a result, you can simply expand your web farm without relying on shared session stores.
  2. Loosely associated: The client application is not connected to or associated with any particular authentication system. The server only performs authentication when the token has been generated and confirmed.
  3. Mobile-Friendly: Cookies and browsers get along well, but managing cookies on native platforms such as Android, iOS, and Windows Phone is difficult. The token-based technique greatly simplifies this.
  4. Statelessness: Tokens are self-contained and contain all necessary information for authentication, allowing the server to be stateless. This scalability advantage enables horizontal scaling and simplified load balancing.
  5. Security: Tokens are often signed or encrypted, making them tamper-proof. They can also have short expiration durations, limiting attackers' window of opportunity.
  6. Decoupling: Token-based authentication allows for Single Sign-On (SSO) across various applications or services without requiring users to provide their credentials.
  7. Flexibility: Tokens can be used for a variety of purposes, such as user authentication, authorization, and granting specific permissions (for example, OAuth2 authorization tokens).
  8. Cross-Origin Resource Sharing (CORS): Tokens can be used with Cross-Origin Resource Sharing headers to secure API access from different domains.
Read More Articles Related to Web API
Summary

Token-based authentication reduces the need to communicate sensitive credentials with each request, which improves security and scalability. Clients exchange credentials in return for a temporary token, which is then utilized for subsequent requests with minimal overhead. This method is suitable for a wide range of clients (browsers, mobile devices, etc.) and streamlines server-side activities. Signed/encrypted tokens, short expirations, and decoupling from session stores are all security benefits.

FAQs

Q1. What is token-based authentication in asp net Web API?

Token-based authentication for web APIs refers to the method of authenticating individuals or processes for cloud-based services. The authentication service checks the user's identity and issues a token after the user's application sends a request to it. The user can now access the application.

Q2. What is API token authentication?

API tokens are short pieces of code that are used to secure API access. These short strings are delivered to API servers, where they function as identification, demonstrating if the user or application has access to the API. They aim to provide both information and authentication to the API server.

Q3. What Is Token-based Authentication?

Token-based authentication is a technique that uses encrypted security tokens to authenticate users. It allows users to authenticate themselves to websites, which generates a unique encrypted authentication token.

Q4. What is the distinction between API key authentication and token-based authentication?

API key - A value supplied by code when accessing an API to identify and authorize the caller. It is often a large string of characters and numbers and is intended to be utilized automatically. Token - A little piece of data that indicates a user session or a set of privileges. Individual users can only utilize it for a limited time.

Q5. Why do APIs use tokens?

To allow an application to access an API, access tokens are used in token-based authentication. A Calendar application, for example, requires access to a cloud-based Calendar API to read the user's planned events and add new events.
Share Article
About Author
Gowtham K (Microsoft MVP and Sr. Software Engineer)

He is having around 5 years of working experience in various technologies like C#, ASP.NET, MVC, Azure, JavaScript, jQuery, CSS and HTML. He loves to work on various web technologies, his passion is to learn, experiment, and share knowledge.
Learn to Crack Your Technical Interview

Accept cookies & close this