ASP.NET Web API Basic Authentication

ASP.NET Web API Basic Authentication

In this article, I am going to discuss how to implement the ASP.NET Web API Basic Authentication step by step with an example. Please read our previous article where we discussed the basics of Authentication and Authorization in Web API. As part of this article, we are going to discuss the following pointers.

  1. Why do we need Authentication in Web API?
  2. How does Basic Authentication Work in Web API?
  3. How to Implement Basic Authentication in ASP.NET Web API?
  4. How to Enable Basic Authentication in Web API?
  5. Testing the ASP.NET Web API Basic Authentication using Postman
Why do we need Authentication in Web API?

Let’s start the discussion with one of the Rest Constraint i.e. Stateless Constraint. The Stateless Constraint is one of the Rest Constraints which states that the communication between the client and server must be stateless between the requests. This means that we should not be storing the client information on the server which required to process the request. The request that is coming from the client should contain all the necessary information that is required by the server to process that request. This ensures that each request coming from the client can be treated independently by the server.

The above approach is fine and the advantage is that we can separate the client or server at any given point in time without affecting others. Here, the client can be any type of application including JavaScript or any other programming language like Java, PHP, or C#. The server does not remember the client once the request has been processed, So, each and every request coming from the client is new to the server and the server needs to check the request (most of the time the HTTP header) to identify the user. 

So, in order to process the request by the server, the client needs to pass its credentials with each and every request and then the server will check and match the credentials with any persistent storage (most of the time it may be a database). If the credentials are found in the persistent storage then the server will treat that HTTP request as a valid request and process it else it simply returns an unauthorized error to the client.

We can implement Authentication and Authorization in many ways in an application. Here, in this article, I am going to discuss how to implement ASP.NET Web API Basic Authentication.

How does Basic Authentication Work in Web API?

Before implementing the Basic Authentication in ASP.NET Web API, let us first understand how does the basic authentication work in Web API? To understand how does basic authentication works, please have a look at the following diagram.

How does Basic Authentication Work in ASP.NET Web API?

In Basic Authentication, if the client didn’t send the credentials in the request header (most of the time it is Authorization header), then the server will return 401 (Unauthorized). The response will also include a WWW-Authenticate header, indicating that the server supports Basic Authentication and that you can see in the above image for the first request which does not include the Authorization header.

The client sends another request to the server, with the client credentials in the Authorization header. Generally, the client credentials are formatted as the string “name:password“, base64-encoded format and this time server validates the client and processes the request and if everything is fine, then you will get 200 OK status which you can see in the above image for the second request.

In Basic Authentication, as we attach the sensitive data (i,e. username and password) in each and every HTTP request, it should be transferred in an encoded format (base64-encoded format) and the protocol should be HTTPS, then only we can protect our data over the internet.

The ASP.NET Web API Basic Authentication is performed within the context of a “realm.” The server includes the name of the realm in the WWW-Authenticate header. The user’s credentials are valid within that realm. The exact scope of a realm is defined by the server. For example, you might define several realms in order to partition resources.

Implementing Basic Authentication in ASP.NET Web API

First, create an ASP.NET Web Application with the name BasicAuthenticationWEBAPI (you can give any name) as shown in the below image.

Implementing Basic Authentication in ASP.NET Web API

Once you click on the OK button, it will open the “Select a template” window. From the “Select a template” window choose

  1. Empty template
  2. Web API Checkbox
  3. No Authentication

And finally, click on the OK button as shown below

Selecting Project Template in Web API for Basic Authentication

Once you click on the OK Button it will take some time to create the project for us.

Creating Models

Now we need to create two models i.e. User and EmployeeSo Right-click on the Models folder and add a class file with the Name User.cs and then copy and paste the below code into it. This is a very simple class having only three properties i.e. ID, UserName and Password.

namespace BasicAuthenticationWEBAPI.Models
{
    public class User
    {
        public int ID { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
    }
}

Similarly, right-click on the Models folder and add a class file with the Name Employee.cs and then copy and paste the below code into it. This is also a very simple class having 5 properties i.e. ID, Name, Gender, Dept, and Salary.

namespace BasicAuthenticationWEBAPI.Models
{
    public class Employee
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Gender { get; set; }
        public string Dept { get; set; }
        public int Salary { get; set; }
    }
}
Creating Business Layer:

Now we will create two classes that will return the list of users and the list of employees. Right-click on the Models folder and add a class file with the Name UserBL.cs and then copy and paste the below code. As you can see, here we created one method to return the list of users. In real-time, you will get the list of users from a database, but here, we are hardcoded the user’s list.

namespace BasicAuthenticationWEBAPI.Models
{
    public class UsersBL
    {
        public List<User> GetUsers()
        {
            // In Real-time you need to get the data from any persistent storage
            // For Simplicity of this demo and to keep focus on Basic Authentication
            // Here we are hardcoded the data

            List<User> userList = new List<User>();

            userList.Add(new User()
            {
                ID = 101,
                UserName = "MaleUser",
                Password = "123456"
            });

            userList.Add(new User()
            {
                ID = 101,
                UserName = "FemaleUser",
                Password = "abcdef"
            });

            return userList;
        }
    }
}

Similarly, right-click on the Models folder and add a class file with the Name EmployeeBL.cs and then copy and paste the below code into it. As you can see, here we created one method to return the list of employees. In real-time, you will get the list of employees from a database, but here, we are hardcoded the employee’s list.

namespace BasicAuthenticationWEBAPI.Models
{
    public class EmployeeBL
    {
        public List<Employee> GetEmployees()
        {
            // In Real-time you need to get the data from any persistent storage
            // For Simplicity of this demo and to keep focus on Basic Authentication
            // Here we hardcoded the data
            List<Employee> empList = new List<Employee>();
            for (int i = 0; i < 10; i++)
            {
                if (i > 5)
                {
                    empList.Add(new Employee()
                    {
                        ID = i,
                        Name = "Name" + i,
                        Dept = "IT",
                        Salary = 1000 + i,
                        Gender = "Male"
                    });
                }
                else
                {
                    empList.Add(new Employee()
                    {
                        ID = i,
                        Name = "Name" + i,
                        Dept = "HR",
                        Salary = 1000 + i,
                        Gender = "Female"
                    });
                }
            }

            return empList;
        }
    }
}

Now, we need to create a class that will check whether the username and password are valid or not. Right-click on the Models folder and add a class file with the Name UserValidate.cs and then copy and paste the following code into it. As you can see, here, the Login method takes the username and password as input parameters. Then it will check whether the username and password are valid or not. If valid, then it returns TRUE indicating the user is valid else returns FALSE indicating the user is invalid.

namespace BasicAuthenticationWEBAPI.Models
{
    public class UserValidate
    {
        //This method is used to check the user credentials
        public static bool Login(string username, string password)
        {
            UsersBL userBL = new UsersBL();
            var UserLists = userBL.GetUsers();
            return UserLists.Any(user =>
                user.UserName.Equals(username, StringComparison.OrdinalIgnoreCase)
                && user.Password == password);
        }
    }
}
Create a Basic Authentication Filter in ASP.NET Web API

Right Click on the Models folder and add a class file with the name BasicAuthenticationAttribute and then copy and paste the following code in it. Here, the BasicAuthenticationAttribute class is inherited from the AuthorizationFilterAttribute class and overrides the OnAuthorization method which makes this class an AuthorizationFilter and can be applied like other attributes to the action methods or at the Controller level. Here, first, we are checking the Authorization header and if it is null, we are simply returning an Unauthorized error to the client. If the Authorization header is not null, then we are taking the Authorization header value, then we decode the value and then we split the decoded value and get the user name and password. Then we call the Login method of the UserValidate class to check if the user is a valid user or not. If the user is not valid, then we return an Unauthorized error to the client else we will proceed with the request.

using System; 
using System.Net; 
using System.Net.Http; 
using System.Security.Principal; 
using System.Text; 
using System.Threading; 
using System.Web; 
using System.Web.Http.Controllers; 
using System.Web.Http.Filters;
namespace BasicAuthenticationWEBAPI.Models
{
    public class BasicAuthenticationAttribute : AuthorizationFilterAttribute
    {
        private const string Realm = "My Realm";
        public override void OnAuthorization(HttpActionContext actionContext)
        {
            //If the Authorization header is empty or null
            //then return Unauthorized
            if (actionContext.Request.Headers.Authorization == null)
            {
                actionContext.Response = actionContext.Request
                    .CreateResponse(HttpStatusCode.Unauthorized);

                // If the request was unauthorized, add the WWW-Authenticate header 
                // to the response which indicates that it require basic authentication
                if (actionContext.Response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    actionContext.Response.Headers.Add("WWW-Authenticate",
                        string.Format("Basic realm=\"{0}\"", Realm));
                }
            }
            else
            {
                //Get the authentication token from the request header
                string authenticationToken = actionContext.Request.Headers
                    .Authorization.Parameter;

                //Decode the string
                string decodedAuthenticationToken = Encoding.UTF8.GetString(
                    Convert.FromBase64String(authenticationToken));

                //Convert the string into an string array
                string[] usernamePasswordArray = decodedAuthenticationToken.Split(':');

                //First element of the array is the username
                string username = usernamePasswordArray[0];

                //Second element of the array is the password
                string password = usernamePasswordArray[1];

                //call the login method to check the username and password
                if (UserValidate.Login(username, password))
                {
                    var identity = new GenericIdentity(username);

                    IPrincipal principal = new GenericPrincipal(identity,null);
                    Thread.CurrentPrincipal = principal;

                    if (HttpContext.Current != null)
                    {
                        HttpContext.Current.User = principal;
                    }
                }
                else
                {
                    actionContext.Response = actionContext.Request
                        .CreateResponse(HttpStatusCode.Unauthorized);
                }
            }
        }
    }
}
Adding WebAPI2 Empty Controller

Right-click on the Controllers folder and select Add => Controller which will open the window to select the controller as shown below.

Adding Web API 2 Empty Controller for Basic Authentication

From this window select Web API 2 Controller – Empty and click on the Add button, which will open another window to give a name to your controller as shown below.

Providing Controller Name in ASP.NET Web API Application

Provide the controller name as Employee and click on the Add button which will add Employee Controller within the controller folder.

Enable Web API Basic Authentication

We can enable basic authentication in many different ways by applying the BasicAuthenticationAttribute. We can apply the BasicAuthenticationAttribute attribute on a specific controller, specific action, or globally which will be applicable to all Web API controllers and action methods.

To enable the basic authentication across the entire ASP.NET Web API application, register the BasicAuthenticationAttribute as a filter using the Register() method in WebApiConfig class as shown in the below image.

Configuring Web API Basic Authentication

We can also apply the BasicAuthenticationAttribute attribute on a specific controller which will enable the basic authentication for all the methods that are present in that controller as shown in the below image.

Applying Web API Basic Authentication at Controller level

You can also enable the basic authentication at the action method level as shown in the below image which is only applicable to that particular action method which is decorated with the BasicAuthenticationAttribute.

Applying Web API Basic Authentication at Action level

Let’s first add an action method to the Employee Controller with the following business requirements. As we have two users i.e. MaleUser and FemaleUser and if the user login with the MaleUser username we want to display all the “male” employees and if the user login with the FemaleUser username we want to display all the female employees. Along with the above business requirement, we also enable basic authentication at the action method level.

Add the following action method within the Employee controller
namespace BasicAuthenticationWEBAPI.Controllers
{  
    public class EmployeeController : ApiController
    {
        [BasicAuthentication]
        public HttpResponseMessage GetEmployees()
        {
            string username = Thread.CurrentPrincipal.Identity.Name;

            var EmpList = new EmployeeBL().GetEmployees();

            switch (username.ToLower())
            {
                case "maleuser":
                    return Request.CreateResponse(HttpStatusCode.OK,
                        EmpList.Where(e => e.Gender.ToLower() == "male").ToList());
                case "femaleuser":
                    return Request.CreateResponse(HttpStatusCode.OK,
                        EmpList.Where(e => e.Gender.ToLower() == "female").ToList());
                default:
                    return Request.CreateResponse(HttpStatusCode.BadRequest);
            }
        }
    }
}
Testing the Web API Basic Authentication using Postman

If you are new to the postman, I strongly recommended you to read the following article, where I discussed how to download and use postman to test rest services.

https://dotnettutorials.net/lesson/how-to-use-postman-to-test-web-api/

Let’s first make a request without passing the authorization header. Set the method type as GET, provide the request URI and click on the Send button as shown in the below image.

ASP.NET Web API Basic Authentication

Here you can observe that you will get a 401 status code which is Unauthorized. Let’s make the request to use the Authorization header. The username and password need to be a colon (:) separated and must be in base64 encoded. To do so, just use the following website

https://www.base64encode.org/

Enter the username and password separated by a colon (:) in the “Encode to Base64 format” textbox, and then click on the “Encode” button as shown in the below diagram which will generate the Base64 encoded value.

ASP.NET Web API Basic Authentication

Once you generate the Base64 encoded string, let’s see how to use basic authentication in the header to pass the Base64 encoded value. Here we need to use the Authorization header and the value will be the Base64 encoded string followed the “BASIC” as shown below.

Authorization: BASIC TWFsZVVzZXI6MTIzNDU2

ASP.NET Web API Basic Authentication

Once you click on the Send button, you can see that the status code is 200 as expected.

That’s it for today. In the next article, I am going to discuss how to implement Role-Based ASP.NET Web API Basic Authentication along with I will also discuss the advantages and disadvantages of using ASP.NET Web API Basic Authentication. Here, in this article, I try to explain the ASP.NET Web API Basic Authentication step by step with an example. I hope you enjoy this Web API Basic Authenticationarticle.

20 thoughts on “ASP.NET Web API Basic Authentication”

  1. That’s exactly I was looking for , explained every step in a tidy manner along with using same over Postman. Shall get back if I face an issue, I’ll be implementing it on Tuesday.

  2. Excellent article, This is well explanation about web api basic authentication, thanks for this awesome post, that all I need it !!!

  3. New to web API and c# in general. First question, why encode username and password if it can be simply decoded anyway?

  4. adeyinkaroyal

    The encoding here is just for demonstration purpose only, in real life scenario, the username and the password or the identity model you plan using will be encrypted with-in your application before encoding it into Base64 and then provided to the user/api consumer to be use as authorization token.

    Why encoding to Base64? Remember some passwords like: blabla!&%+myName, this is a valid user-password but if your pass this raw in your Authorization Header, it can result into HttpRequestValidationException but if your encode it to Base64, you have: YmFiYSE8PiYlK215TmFtZQ which can safely pass through the HttpRequestValidation.

  5. I’m probably the only one experiencing this, but please I need help, I noticed there’s no route attribute in the employee controller, or even a http verb attribute. When I try to hit the example endpoint using postman, it just keeps requesting forever then times out. Please help me

  6. Update to my issue above, I get the expected response when I request using “https://localhost:port/….” in my browser but not with “http://localhost:port/…”

  7. So apparently, I was using the ssl url with http, did found the http url in the solutions properties, that seemingly simple thing took me a while, resolved

  8. Nice article, but i have doubt in BasicAuthenticationAttribute at : string authenticationToken = actionContext.Request.Headers.Authorization.Parameter;

    I think it should be string authenticationToken = actionContext.Request.Headers
    .Authorization.Scheme;

    because when i use .Parameter it throws exception and when i change it to .Scheme it works.

    Also i can see two simultaneous 2 calls to BasicAuthenticationAttribute, please explain this as well.
    Thanks,
    Sachin

  9. Very nice explaination…i am rather confused between using filters for authentication and authorization and forms, windows and passport authentication techniques.
    Can you please help me distinguish between these two?

  10. without writing this line of code config.MapHttpAttributeRoutes(); in weapiconfig class i am able to execute the code. could you pls clarify?

  11. Madhumitha Gopalakrishnan

    but you simply ask to copy paste the code ,where can i get to know how to write this authorization and authentication step by step

  12. The explanation is very wonderful, sir, and your way of explaining is very beautiful, even sometimes better than some books. I follow all your articles and learn from you, but I faced a problem, which is that I was following the explanation with .net Core 6, and now I want to learn from you Identity and Api Security, and I did not find them in the content for the Core. I only found old content with the .net framework. I hope you will continue. This content is updated for the current version of .net, .net core 8, or any version that is closest to my understanding, such as .net core 6 or 7. Thank you very much for your presence once again.

Leave a Reply

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