Level: Intermediate; Requirements: Must have some experience in C# and WCF Services
Suppose you have a database hosted on a server and you developed a Windows Desktop application or a mobile app that connects to that database using a connection string. Now, whenever you want to send something to that database from that application, you need to send the server address, username, and password of the database (which is in the connection string). This exposes the database to the end-user. Anyone can decompile the application executable file and extract the connection string.
So, how can we avoid this BIGGG security problem? Well, the answer is very simple, Web Services. The application will call the web-service which stores the connection string on the server and then web-service will request the data from the database and returns it to the client application.
But now the web-service is exposed on the Internet. Anyone can call the service using its URL and then access the database. So, how we can avoid it? There are many methods for this, but in this article, I will explain how to implement a very basic Token Based method of authentication? But first I will briefly explain the framework in which I will create our web-service, which is Windows Communication Foundation framework or WCF in short.
What is WCF?
WCF (Windows Communication Foundation) is a unified programming model for building service-oriented applications. It is a highly customizable web-service framework. It provides many options to change the behavior of your web-service the way you want. WCF service comes with many inbuilt authentication mechanisms that I will not cover in this article. Instead, I will implement my own very simple authentication system. The code can be used in production but this code is just for learning purposes and is very basic.
Token Based Authentication
Now even after deploying our database code inside a web-service, our database is still not secured. The reason is that the access to the web-service is still open to anyone who has the URL to the web-service. So, this can be solved using a very simple method known as Token Based Authentication.
Token Based Authentication works like this:
- The client application sends username and password to the web-service.
- The web-service checks if the username and password combination is correct.
- If correct then it generates a token which is nothing but a random unique string (or a hash) and sends it to the client.
- Now whenever the client wants to consume a web-service function, it must send the token with its request.
- The web-service checks if the token matches any tokens in the database that are not expired. If the match is found then it allows the request otherwise raises an unauthorized access error.
So, now let’s code these steps.
Note: For storing the authentication information, I will recommend you to use a seperate database instead of mixing it with the other user data.
I will not go into steps of creating a WCF service. But don’t worry if you don’t know I will explain it in one of the future posts. Also, to save authentication information I am using DataSet and saving it to a local XML file. I will not explain how to save DataSet in an XML file? But if you want to learn it then go to following link: https://aishwaryashiva.com/how-to-save-dataset-in-an-xml-file/
Creating Web-Service Methods
Now let’s create some methods at the web-service end. The first method is the one that will accept the username and password and generates a unique string that will act as a token.
Read the comments in front and above of each code statement to understand what it does.
[csharp]
public string GetToken(string username, string password)
{
bool IsLoginValid = //check here if the username and password combination exists in the database
if (IsLoginValid)
{
var token = Guid.NewGuid().ToString(); //If username and password combination found in the database then generate a token.
bool dbExists = LocalDataAccess.Reload(); //This just checks if the local database(the dataset saved in a file) exists. The details of the method are in "How to save dataset in an XML file?" article.
bool rowFound = false; //This checks if token for particular username already exists in the DataSet
if (dbExists)
{
//Checking if the DataSet has tables, table with the name ‘Sessions’ and table ‘Sessions has rows
if (LocalDataAccess.LocalDB.Tables.Count > 0 && LocalDataAccess.LocalDB.Tables["Sessions"] != null && LocalDataAccess.LocalDB.Tables["Sessions"].Rows.Count > 0)
{
//Traverse each row of the database table ‘Sessions’
foreach (DataRow dr in LocalDataAccess.LocalDB.Tables["Sessions"].Rows)
{
//Check if the username already exists. This is just to avoid multiple token entries for single user.
if (dr["Username"].ToString().Equals(username))
{
dr["Token"] = token; //if username found then update its token
dr["ExpiryDateTime"] = DateTime.Now.AddHours(12); //And set the token expiry time.
rowFound = true;
}
}
}
}
if (rowFound == false) //If row for the username not found in the database
{
//then add the username, token and token expiry date in the database.
LocalDataAccess.LocalDB.Tables["Sessions"].Rows.Add(username, DateTime.Now.AddHours(12), token);
}
//Save the database to the file system
LocalDataAccess.Update();
//Reload the database with updated values.
LocalDataAccess.Reload();
//return the token to the client so that it can use to make web-service requests.
return token;
}
else
return null; //when username and password doesn’t match.
}
[/csharp]
So, now we have a method that will do four tasks: check for valid login, generate a token, save token in the local database and send it the client.
Now, we will create a method that will check the validity of the token whenever the client wants to execute a web-service method. For this, we need to pass the token and the username with the method.
Suppose, we have a method:
[csharp]
void AddEmployee(string EmployeeName, string username, string token)
{
AuthToken(username, token); //This method will check if username and token combination exists, and sets the connection string for database access.
…… // add your database code here.
}
[/csharp]
This is some example method that allows a client to add employee information in the database. But to do that, it will need to connect to the database using a connection string.
Let’s suppose we take a variable:
[csharp]
string connectionString = "";
[/csharp]
Declare this private variable in the class where your database methods are or wherever you feel good. This variable will be assigned by method AuthToken() like this:
[csharp]
public void AuthToken(string username, Guid token)
{
//Reloading data from filesystem to the DataSet
LocalDataAccess.Reload();
//Get the row that contains username and token combination
DataRow dr = LocalDataAccess.LocalDB.Tables["Sessions"].Select("[Username]=’" + username + "’ AND [Token]=’" + token + "’").FirstOrDefault();
if (dr != null)
{
//This checks if the token is expired or not
if (DateTime.Now < DateTime.Parse(dr["ExpiryDateTime"].ToString()))
//If token is not expired then set the connection string from the web.config file.
connectionString = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
}
}
[/csharp]
So now whenever the client wants to call a database method on the web-serivce, it needs to pass username and token to the database method. And before using the connection string, you must call the AuthToken() method.
Conclusion
This was a very simple token based authentication using C# and WCF services. The objective of this article was to show you how a basic token authentication works. You can research more on the web to learn more advanced tactics that can be used to implement a highly secure token based authentication.
So that’s all for now. I hope you get the basic idea on how to implement token based authentication in your application. If you still have some queries or facing any issue, leave a comment and I will help you implement this in your application.
See you in next post.
Code Awesomely.. bye. 🙂
Nice article. Very simple to understand.
Thanks 🙂
can i provide the code