Loading

ASP.NET Web API

How to Consume Refresh Token in C# Client?. The Complete ASP.NET Web API Developer Course 2023 [Videos].

In this Video, I will discuss how to Consume Refresh Token in C# Client application. Please read the following three Videos, before proceeding to this Video as we are going to consume the services that we created in our previous Videos.

Token Based Authentication in Web API: In this Video, we discussed how to implement and use the Token Based Authentication in Web API.

Client Validation in Token Based Authentication: In this Video, we discussed how to validate the clients while generating the token in Web API.

Generating Refresh Token in Web API: In this Video, we discussed how to Generate Refresh Token in Web API.

Let us discuss the step by step procedure to Consume Refresh Token in C#. But before that lets modify the Test Controller of our Web API application that we created in our previous application as shown below.

Step1: Modifying the Test Controller
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()));
}
}
}
Step2: Creating the UserTokenMaster table

In the client side, we need to store the token in the UserTokenMaster table as shown below

Consume Refresh Token in C#

Please use the below SQL Script to create the required database.

CREATE DATABASE Test_DB
GO
USE Test_DB
CREATE TABLE UserTokenMaster
(
UserName VARCHAR(50) PRIMARY KEY,
UserPassword VARCHAR(50),
AccessToken VARCHAR(500),
RefreshToken VARCHAR(100),
TokenExpiredTime DATETIME
)
GO

Step3: Create a new console application with the name RefreshTokenClient1.

Step4: Add ADO.NET Entity Data Model

Here, we need to add ADO.NET Entity Data Model Database First approach against the Test_DB and add the UserTokenMaster to the EDMX that we created in Step2. So once you add the table, the EDMX File should be as shown below

Consume Refresh Token in C#

Step5: Add Token class

Now we need to add a class file with the name Token to the project. And then copy and paste the following code.

using Newtonsoft.Json;
using System;
namespace RefreshTokenClient1
{
// The body of the response from API is a JSON object that
// contains the following properties (and a couple of others
public class Token
{
[JsonProperty("access_token")]
public string AccessToken { get; set; }
[JsonProperty("token_type")]
public string TokenType { get; set; }
[JsonProperty("expires_in")]
public int ExpiresIn { get; set; }
[JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
public string Error { get; set; }
public DateTime ExpiredDateTime { get; set; }
}
}
Step6: Adding UserTokenRepository

Now we need to add a class with the name UserTokenRepository and within that class we are going to perform the database operations. So once you add the class, copy and paste the following code.

using System;
using System.Linq;
namespace RefreshTokenClient1
{
class UserTokenRepository : IDisposable
{
// Test_DBEntities it is your context class
Test_DBEntities context = new Test_DBEntities();
public Token GetTokenFromDB(string username, string password)
{
UserTokenMaster userMaster = context.UserTokenMasters.FirstOrDefault(user =>
user.UserName.Equals(username, StringComparison.OrdinalIgnoreCase)
&& user.UserPassword == password);
Token token = null;
if (userMaster != null)
{
token = new Token()
{
AccessToken = userMaster.AccessToken,
RefreshToken = userMaster.RefreshToken,
ExpiredDateTime = (DateTime)userMaster.TokenExpiredTime
};
}
return token;
}
//Adding Token into the DB
public bool AddUserTokenIntoDB(UserTokenMaster userTokenMaster)
{
//First Check the existance of the Token in the DB
var tokenMaster = context.UserTokenMasters.FirstOrDefault(x => x.UserName == userTokenMaster.UserName
&& x.UserPassword == userTokenMaster.UserPassword);
if (tokenMaster != null)
{
context.UserTokenMasters.Remove(tokenMaster);
}
context.UserTokenMasters.Add(userTokenMaster);
bool isAdded = context.SaveChanges() > 0;
return isAdded;
}
public void Dispose()
{
context.Dispose();
}
}
}
Step7: Modify the Program class

Here we need to implement the logic to get the access token and refresh from token API and then storing the Token into our database.

Note: The editor we are using to display the code snippet is not showing the following code, so we display the code as it is. The following code is self-explained, please go through the comments.

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
namespace RefreshTokenClient1
{
class Program
{
// When your application is registered you will get
// the client id and secret from the API
private static string _clientId = “DOTNET”;
private static string _clientSecret = “EEF47D9A-DBA9-4D02-B7B0-04F4279A6D20”;
private static string Username = “”;
private static string Password = “”;
//Store the base address of the web api
//You need to change the PORT number where your WEB API service is running
private static string baseAddress = “http://localhost:65061/”;
static void Main(string[] args)
{
Token token = null;
Username = “Anurag”;
Password = “123456”;
// First get the token from the persistent storage based
// on the username and password
token = (new UserTokenRepository()).GetTokenFromDB(Username, Password);
//Then check the existing token and its expiration datetime
if (token != null && DateTime.Now < token.ExpiredDateTime)
{
//use the existing token
}
else if (token != null && !string.IsNullOrEmpty(token.RefreshToken))
{
//Get a new access token based on the Refresh Token
token = GetTokens(_clientId, _clientSecret, token.RefreshToken);
}
else
{
//Get a brand new access token
token = GetTokens(_clientId, _clientSecret, null);
}
//If you get the access token, then call the authorized resource
if (!string.IsNullOrEmpty(token.AccessToken))
{
CallAPIResource1(token.AccessToken);
}
else
{
Console.WriteLine(token.Error);
}
Console.ReadLine();
}
//Here we implment the logic to call the authorized resource
private static void CallAPIResource1(string AccessToken)
{
HttpClientHandler handler = new HttpClientHandler();
HttpClient client = new HttpClient(handler);
// Need to set the Access Token in the Authorization Header as shown below
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Bearer”, AccessToken);
// Make a Get request for the authorized resource by invoking
// the PostAsync method on the client object as shown below
var APIResponse = client.GetAsync(baseAddress + “api/test/resource1”).Result;
if (APIResponse.IsSuccessStatusCode)
{
var JsonContent = APIResponse.Content.ReadAsStringAsync().Result;
string Message = JsonConvert.DeserializeObject<string>(JsonContent);
Console.WriteLine(“APIResponse : ” + Message);
}
else
{
Console.WriteLine(“APIResponse, Error : ” + APIResponse.StatusCode);
}
}
//In this method we need to implement the logic whether we need get a brand new access token
// or we need the access token based on the Refresh Token
private static Token GetTokens(string clientId, string clientSecret, string RefreshToken)
{
Token token = null;
if (string.IsNullOrEmpty(RefreshToken))
{
token = GetAccessToken(clientId, clientSecret, Username, Password);
}
else
{
token = GetAccessTokenByRefreshToken(clientId, clientSecret, RefreshToken);
// The Refresh token can become invalid for several reasons
// such as invalid cliendid and secret or the users password has changed.
// In Such cases issue a brand new access token
if (!string.IsNullOrEmpty(token.Error))
{
token = GetAccessToken(clientId, clientSecret, Username, Password);
}
}
if (!string.IsNullOrEmpty(token.Error))
{
throw new Exception(token.Error);
}
else
{
//Need to store the token in any presistent storage
token.ExpiredDateTime = DateTime.Now.AddSeconds(token.ExpiresIn);
//Create an object of type UserTokenMaster
UserTokenMaster userTokenMaster = new UserTokenMaster()
{
UserName = Username,
UserPassword = Password,
AccessToken = token.AccessToken,
RefreshToken = token.RefreshToken,
TokenExpiredTime = token.ExpiredDateTime
};
bool IsAddeded = (new UserTokenRepository()).AddUserTokenIntoDB(userTokenMaster);
if (IsAddeded)
{
token.Error = “Error Occurred while saving the Token into the DB”;
}
}
return token;
}
//This method is used to get a new access token
public static Token GetAccessToken(string clientId, string clientSecret, string username, string password)
{
Token token = new Token();
HttpClientHandler handler = new HttpClientHandler();
HttpClient client = new HttpClient(handler);
// Need to set the Client ID and Client Secret in the Authorization Header
// in Base64 Encoded Format using the Basic Authentication as shown below
string ClientIDandSecret = clientId + “:” + clientSecret;
var authorizationHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes(ClientIDandSecret));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Basic”, authorizationHeader);
// Create a dictionary which contains the request form data, here we need to set
// the username, password and grant_type as shown below
var RequestBody = new Dictionary<string, string>
{
{“grant_type”, “password”},
{“username”, username},
{“password”, password},
};
//Make a Post request by invoking the PostAsync method on the client object as shown below
var tokenResponse = client.PostAsync(baseAddress + “token”, new FormUrlEncodedContent(RequestBody)).Result;
if (tokenResponse.IsSuccessStatusCode)
{
var JsonContent = tokenResponse.Content.ReadAsStringAsync().Result;
token = JsonConvert.DeserializeObject<Token>(JsonContent);
token.Error = null;
}
else
{
token.Error = “GetAccessToken failed likely due to an invalid client ID, client secret, or invalid usrename and password”;
}
return token;
}
//This method is used to get a new access token based on the Refresh Token
public static Token GetAccessTokenByRefreshToken(string clientId, string clientSecret, string refreshToken)
{
Token token = new Token();
HttpClientHandler handler = new HttpClientHandler();
HttpClient client = new HttpClient(handler);
// Need to set the Client ID and Client Secret in the Authorization Header
// in Base64 Encoded Format using Basic Authentication as shown below
string ClientIDandSecret = clientId + “:” + clientSecret;
var authorizationHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes(ClientIDandSecret));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(“Basic”, authorizationHeader);
// Create a dictionary which contains the refresh token, here we need to set
// the grant_type as refresh_token as shown below
var RequestBody = new Dictionary<string, string>
{
{“grant_type”, “refresh_token”},
{“refresh_token”, refreshToken}
};
//Make a Post request by invoking the PostAsync method on the client object as shown below
var tokenResponse = client.PostAsync(baseAddress + “token”, new FormUrlEncodedContent(RequestBody)).Result;
if (tokenResponse.IsSuccessStatusCode)
{
var JsonContent = tokenResponse.Content.ReadAsStringAsync().Result;
token = JsonConvert.DeserializeObject<Token>(JsonContent);
token.Error = null;
}
else
{
token.Error = “GetAccessToken by Refresh Token failed likely due to an invalid client ID, client secret, or it has been revoked by the system admin”;
}
return token;
}
}
}

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
namespace RefreshTokenClient1
{
class Program
{
// When your application is registered you will get
// the client id and secret from the API
private static string _clientId = "DOTNET";
private static string _clientSecret = "EEF47D9A-DBA9-4D02-B7B0-04F4279A6D20";
private static string Username = "";
private static string Password = "";
//Store the base address of the web api
//You need to change the PORT number where your WEB API service is running
private static string baseAddress = "http://localhost:65061/";
static void Main(string[] args)
{
Token token = null;
Username = "Anurag";
Password = "123456";
// First get the token from the persistent storage based
// on the username and password
token = (new UserTokenRepository()).GetTokenFromDB(Username, Password);
//Then check the existing token and its expiration datetime
if (token != null && DateTime.Now < token.ExpiredDateTime)
{
//use the existing token
}
else if (token != null && !string.IsNullOrEmpty(token.RefreshToken))
{
//Get a new access token based on the Refresh Token
token = GetTokens(_clientId, _clientSecret, token.RefreshToken);
}
else
{
//Get a brand new access token
token = GetTokens(_clientId, _clientSecret, null);
}
//If you get the access token, then call the authorized resource
if (!string.IsNullOrEmpty(token.AccessToken))
{
CallAPIResource1(token.AccessToken);
}
else
{
Console.WriteLine(token.Error);
}
Console.ReadLine();
}
//Here we implment the logic to call the authorized resource
private static void CallAPIResource1(string AccessToken)
{
HttpClientHandler handler = new HttpClientHandler();
HttpClient client = new HttpClient(handler);
// Need to set the Access Token in the Authorization Header as shown below
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
// Make a Get request for the authorized resource by invoking
// the PostAsync method on the client object as shown below
var APIResponse = client.GetAsync(baseAddress + "api/test/resource1").Result;
if (APIResponse.IsSuccessStatusCode)
{
var JsonContent = APIResponse.Content.ReadAsStringAsync().Result;
string Message = JsonConvert.DeserializeObject<string>(JsonContent);
Console.WriteLine("APIResponse : " + Message);
}
else
{
Console.WriteLine("APIResponse, Error : " + APIResponse.StatusCode);
}
}
//In this method we need to implement the logic whether we need get a brand new access token
// or we need the access token based on the Refresh Token
private static Token GetTokens(string clientId, string clientSecret, string RefreshToken)
{
Token token = null;
if (string.IsNullOrEmpty(RefreshToken))
{
token = GetAccessToken(clientId, clientSecret, Username, Password);
}
else
{
token = GetAccessTokenByRefreshToken(clientId, clientSecret, RefreshToken);


if (!string.IsNullOrEmpty(token.Error))
{
token = GetAccessToken(clientId, clientSecret, Username, Password);
}
}
if (!string.IsNullOrEmpty(token.Error))
{
throw new Exception(token.Error);
}
else
{
//Need to store the token in any presistent storage
token.ExpiredDateTime = DateTime.Now.AddSeconds(token.ExpiresIn);
//Create an object of type UserTokenMaster
UserTokenMaster userTokenMaster = new UserTokenMaster()
{
UserName = Username,
UserPassword = Password,
AccessToken = token.AccessToken,
RefreshToken = token.RefreshToken,
TokenExpiredTime = token.ExpiredDateTime
};
bool IsAddeded = (new UserTokenRepository()).AddUserTokenIntoDB(userTokenMaster);
if (IsAddeded)
{
token.Error = "Error Occurred while saving the Token into the DB";
}
}
return token;
}
//This method is used to get a new access token
public static Token GetAccessToken(string clientId, string clientSecret, string username, string password)
{
Token token = new Token();
HttpClientHandler handler = new HttpClientHandler();
HttpClient client = new HttpClient(handler);
// Need to set the Client ID and Client Secret in the Authorization Header
// in Base64 Encoded Format using the Basic Authentication as shown below
string ClientIDandSecret = clientId + ":" + clientSecret;
var authorizationHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes(ClientIDandSecret));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authorizationHeader);
// Create a dictionary which contains the request form data, here we need to set
// the username, password and grant_type as shown below
var RequestBody = new Dictionary<string, string>
{
{"grant_type", "password"},
{"username", username},
{"password", password},
};
//Make a Post request by invoking the PostAsync method on the client object as shown below
var tokenResponse = client.PostAsync(baseAddress + "token", new FormUrlEncodedContent(RequestBody)).Result;
if (tokenResponse.IsSuccessStatusCode)
{
var JsonContent = tokenResponse.Content.ReadAsStringAsync().Result;
token = JsonConvert.DeserializeObject<Token>(JsonContent);
token.Error = null;
}
else
{
token.Error = "GetAccessToken failed likely due to an invalid client ID, client secret, or invalid usrename and password";
}
return token;
}
//This method is used to get a new access token based on the Refresh Token
public static Token GetAccessTokenByRefreshToken(string clientId, string clientSecret, string refreshToken)
{
Token token = new Token();
HttpClientHandler handler = new HttpClientHandler();
HttpClient client = new HttpClient(handler);
// Need to set the Client ID and Client Secret in the Authorization Header
// in Base64 Encoded Format using Basic Authentication as shown below
string ClientIDandSecret = clientId + ":" + clientSecret;
var authorizationHeader = Convert.ToBase64String(Encoding.UTF8.GetBytes(ClientIDandSecret));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authorizationHeader);
// Create a dictionary which contains the refresh token, here we need to set
// the grant_type as refresh_token as shown below
var RequestBody = new Dictionary<string, string>
{
{"grant_type", "refresh_token"},
{"refresh_token", refreshToken}
};
//Make a Post request by invoking the PostAsync method on the client object as shown below
var tokenResponse = client.PostAsync(baseAddress + "token", new FormUrlEncodedContent(RequestBody)).Result;
if (tokenResponse.IsSuccessStatusCode)
{
var JsonContent = tokenResponse.Content.ReadAsStringAsync().Result;
token = JsonConvert.DeserializeObject<Token>(JsonContent);
token.Error = null;
}
else
{
token.Error = "GetAccessToken by Refresh Token failed likely due to an invalid client ID, client secret, or it has been revoked by the system admin";
}
return token;
}
}
}

Thats it. Run the application and see everything is working as expected. In the next Video, I will discuss how to consume Refresh Token using JavaScript.

In this Video, I try to explain how to Consume Refresh Token in C# Client Application with an example. I hope this Video will help you with your need. I would like to have your feedback. Please post your feedback, question, or comments about this Video.

See All

Comments (565 Comments)

Submit Your Comment

See All Posts

Related Posts

ASP.NET Web API / Blog

What is ASP.NET Web API Application?

In this ASP.NET Web API Tutorials series, I covered all the features of ASP.NET Web API. You will learn from basic to advance level features of ASP.NET Web API. The term API stands for “Application Programming Interface” and ASP.NET Web API is a framework provided by Microsoft which makes it easy to build Web APIs, i.e. it is used to develop HTTP-based web services on the top of .NET Framework.
3-Feb-2022 /34 /565

ASP.NET Web API / Blog

How to creat ASP.NET Web API Application using Visual Studio?

In this article, I am going to discuss the step-by-step procedure for Creating ASP.NET Web API Application. Please read our previous article before proceeding to this article where we gave an overview of the ASP.NET Web API framework. As part of this article, we ate going to discuss the following pointers.
3-Feb-2022 /34 /565

ASP.NET Web API / Blog

How to add Swagger in Web API Application?

In this article, I am going to discuss how to add Swagger in Web API Application to document and test restful Web API services. Please read our previous article where we discussed How to Create an ASP.NET Web API Application step by step before proceeding to this article as we are going to work with the same example. As part of this article, we are going to discuss the following pointers.
3-Feb-2022 /34 /565