Client Validation Using Basic Authentication in Web API

Client Validation Using Basic Authentication in Web API

In this article, I am going to discuss how to implement Client Validation Using Basic Authentication in Web API. Please read our previous article before proceeding to this article as we are going to work the same example. In our last article, we discussed how to implement Token Based Authentication in ASP.NET Web API.

If you observed in the last article, we have created the following MyAuthorizationServiceProvider class.

Client Validation Using Basic Authentication in Web API

The first method i.e. ValidateClientAuthentication method is responsible for validating the Client, in the above example, we assume that we have only one client so we’ll always return that it is validated successfully.

Let’s change the requirement. Assume that we have more than one client, who is going to consume our service. In such a case, we need to validate the clients within the ValidateClientAuthentication method.

Let’s see how to achieve this.

For this, we are going to use the following ClientMaster table

Client Validation Using Basic Authentication in Web API

Please use below SQL Script to create and populate the ClientMaster table with some test data.

USE SECURITY_DB
GO

-- Create ClientMaster table
CREATE TABLE ClientMaster
(
  ClientKeyId INT PRIMARY KEY IDENTITY,
  ClientId VARCHAR(500),
  ClientSecret VARCHAR(500),
  ClientName VARCHAR(100),
  CreatedOn DateTime
)
GO

-- Populate the ClientMaster with test data
 INSERT INTO ClientMaster(ClientId, ClientSecret, ClientName, CreatedOn) 
 VALUES(NEWID(), NEWID(), 'My Client1', GETDATE())

 INSERT INTO ClientMaster(ClientId, ClientSecret, ClientName, CreatedOn) 
 VALUES(NEWID(), NEWID(), 'My Client2', GETDATE())

 INSERT INTO ClientMaster(ClientId, ClientSecret, ClientName, CreatedOn) 
 VALUES(NEWID(), NEWID(), 'My Client3', GETDATE())

Once you create the ClientMaster table, then you need to update the EDMX file to add the above ClientMaster table.

Create a class file with the name ClientMasterRepository.cs and then copy and paste the following code.
namespace TokenAuthenticationInWebAPI.Models
{
    public class ClientMasterRepository : IDisposable
    {
        // SECURITY_DBEntities it is your context class
        SECURITY_DBEntities context = new SECURITY_DBEntities();
        
        //This method is used to check and validate the Client credentials
        public ClientMaster ValidateClient(string ClientID, string ClientSecret)
        {
            return context.ClientMasters.FirstOrDefault(user =>
             user.ClientId == ClientID
            && user.ClientSecret == ClientSecret);
        }

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

Here we create the ValidateClient method which is very straightforward. It’s the ClientID and ClientSecret as input parameter and checks in the ClientMaster table whether the client is valid or not and it simply returns the client details.

Now we need to modify the ValidateClientAuthentication() method of MyAuthorizationServerProvider class as shown below.
public override async Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
{
    string clientId = string.Empty;
    string clientSecret = string.Empty;
    // The TryGetBasicCredentials method checks the Authorization header and
    // Return the ClientId and clientSecret
    if (!context.TryGetBasicCredentials(out clientId, out clientSecret))
    {
        context.SetError("invalid_client", "Client credentials could not be retrieved through the Authorization header.");
        context.Rejected();
        return;
    }
    //Check the existence of by calling the ValidateClient method
    ClientMaster client = (new ClientMasterRepository()).ValidateClient(clientId, clientSecret);
    if (client != null)
    {
        // Client has been verified.
        context.OwinContext.Set<ClientMaster>("oauth:client", client);
        context.Validated(clientId);
    }
    else
    {
        // Client could not be validated.
        context.SetError("invalid_client", "Client credentials are invalid.");
        context.Rejected();
    }
    context.Validated();
}

Note: We need to pass the ClientId and ClientSecret using the Basic authentication in the authorization header i.e. in Base64 encoded format.

Modify the GetResource1 action method of the TestController as shown below.

Client Validation Using Basic Authentication in Web API

Testing the API using Postman:

Let’s first create the Base64 Encode value by for the ClientID and ClientSecret by using the following website

https://www.base64encode.org/

Enter the ClientID and ClientSecret separated by a colon (:) in “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.

Client Validation Using Basic Authentication in Web API

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 QzFBMDNCMTAtN0Q1OS00MDdBLUE5M0UtQjcxQUIxN0FEOEMyOjE3N0UzMjk1LTA2NTYtNDMxNy1CQzkxLUREMjcxQTE5QUNGRg==

Let’s see step by step procedure to use the Postman to generate the Access Token

Step1:

Select the Method as POST and provide URI as shown below in the below image

Client Validation Using Basic Authentication in Web API

Step2:

Select the Header tab and provide the Authorization value as shown below.

Authorization: BASIC QzFBMDNCMTAtN0Q1OS00MDdBLUE5M0UtQjcxQUIxN0FEOEMyOjE3N0UzMjk1LTA2NTYtNDMxNy1CQzkxLUREMjcxQTE5QUNGRg==

Client Validation Using Basic Authentication in Web API

Step3:

Select the Body Tab. Then choose x-www-form-urlencoded option and provide the username and password value. Provide the grant_type value as password as shown in the below image,

Client Validation Using Basic Authentication in Web API

Now click on the Send button which will generate the access token as shown below.

Client Validation Using Basic Authentication in Web API

Once the access token is generated, we use that token to access the resources as shown below.

Client Validation Using Basic Authentication in Web API

In the next article, I will discuss how to generate Refresh Token in ASP.NET Web API.

SUMMARY

In this article, I try to explain how to implement Client Validation Using Basic Authentication in Web API with an example. I hope this article will help you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this article.

No HTML was returned.

3 thoughts on “Client Validation Using Basic Authentication in Web API”

  1. Hi, I’ve followed this post and the previous ones, and all was ok but in this one, the Test Resource1 modified as required is not working.
    The Token method works and gives back the Token but the Claims contain only the Username and Password, they do not contain ClientID, ClientSecret, ClientName so maybe I’m doing something wrong in the Client validation that is not setting the Client Data into the claims list.
    Do you have any suggestion?
    Thanks in advance

  2. I’ve found the answer to my previous question, before using the test method it is necessary to add the properties from the Client data to the Claims of the context. My solution is the following:
    public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
    UsersRepository _repo = new UsersRepository();

    var user = _repo.ValidateUser(context.UserName, context.Password);
    if (user == null)
    {
    context.SetError(“invalid_grant”, “Provided username and password is incorrect”);
    return;
    }
    var client = context.OwinContext.Get(“oauth:client”);
    var identity = new ClaimsIdentity(context.Options.AuthenticationType);
    identity.AddClaim(new Claim(ClaimTypes.Role, user.GetRolesString()));
    identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
    identity.AddClaim(new Claim(“Email”, user.Email));
    identity.AddClaim(new Claim(“FullName”, string.Format(user.FullName)));
    identity.AddClaim(new Claim(“FullLogin”, user.ToJson()));
    identity.AddClaim(new Claim(“ClientName”, client.ClientName));
    identity.AddClaim(new Claim(“ClientKeyID”, client.ClientKeyID));
    identity.AddClaim(new Claim(“ClientKeySecret”, client.ClientKeySecret));

    context.Validated(identity);

    }
    This way the properties of the client can be shown in the resource1 method. You can also put the whole class in a claim using a json serialization as I did in my user class.
    HTH
    Sabrina

  3. Hi,
    How to update .edmx file. below suggestion are not working
    Suggestion 1:
    1.Build the project after updating EDMX file.
    2.Right click your .tt file in solution explorer.
    3.Select “Run Custom Tool” option

    Suggestion 2:(on right-click not getting any option like “Update Model from Database”)
    In the Model Browser, right-click the .edmx file and select Update Model from Database.
    Expand the Tables, Views, and Stored Procedures nodes, and check the objects you want to add to the .edmx file.

Leave a Reply

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