Thursday 21 July 2016

Token Based Authentication using ASP.NET Web API 2, Owin, and Identity

A week ago, I was looking at the tutorial of how to setup Asp.Net Web API without Authentication. It was pretty easy and straight forward. But, when you come to a point where you think you need more protection to certain functions, as well as limiting the functions to certain group of users, then you started to think about Web API with Authentication.

There are so many tutorials and examples available in internet about  how to setup Web API with token based authentication. Instead, I am not going into details of how to setup everything or the handshake mechanism, etc. I am going to share and show you what I've encountered, particularly with the desire to move the database out from the original place.

Start

So, I started with creating an ASP.NET web Application. Then, go for Web API template, with authentication type = individual accounts.

Here are some of the tricky things that I have encountered:

  • I started the whole website in debugging mode. Run it under the chrome browser, with the default localhost and the dynamic port generated by VS.  I tested it with "/help".  Hmmm.. looking good. I managed to see the API documentation. This also implies that the Web Api has been setup successfully. 
  • Next, I tried register with a new user. Again, no issue at all. A database with a random name has been created automatically after the call. You should find the database appear in App_Data folder.  Data inserted successfully.
  • This is a LocalDB (with less integration feature). But, this is also a problem for me...  
  • Sample:
    <!--add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-SecuredWebApi-20160720040853.mdf;Initial Catalog=aspnet-SecuredWebApi-20160720040853;Integrated Security=True"
          providerName="System.Data.SqlClient" /--> 
Problem I have encountered
  • I setup a website locally, host the Web Api in my IIS. I tested the newly created website with the same API request ("/help"). As a result,  no issue at all.  Next,  try it out with the registration api. Oh oh...  something wrong. It took few minutes to finish the request. And, it finished with 'request time out' error. Something went wrong with the ConnectionString.  I suspect this could be something to do with the location of the database,  etc.  Anyway, my desire is to move it out from the default location.  It is very handy to have it within the App_Data. But, I prefer to manage it via SQL management studio. 
  • Can I detach it and attach it from one place to another place? Sounds like this is an easy job, which can be done via the attach/detach built-in function. However,  this is the error when I try to attach the database through my SQL management studio (SQL server 2012): 
  • Error: "The database cannot be opened because it is version 706. This server supports version xxx and easier. A downgrade path i s not supported" ! Gosh! ...   
In fact...
  • The database will be generated only after the first call to database related function. Such as "api/account/register". So, let do something before any call to the database. 
Resolved it by:
  • Connection string - Go to Web.Config, change the connection string. Provide the right connection type you need. Re-build the project. Restart the IIS. 
  • Sample:
    <add name="DefaultConnection" connectionString="data source=(local);Initial Catalog=aspnet-SecuredWebApi-20160720040853;persist security info=False;user id=yourID;password=yourPassword;" providerName="System.Data.SqlClient"/>
  • Without warning, I got all the user related tables generated in my local database.  And, I can manage it via the SQL management studio. Bingo!


Walk through screen shots


Create a new project - Asp.Net web application























Select a template

















Create a website to host the Web API


















Add an entry to your local host (if you have more than 1 websites that using the same port











Test the website by calling getting the API documentation ("/help")





































Yeh! at this point, at least you can confirm that the web api is working fine in IIS. 


Next, goto server explorer. Should be still nothing in database connections (oops, I should remove the arrow).

























Change the connection string in Web.Config. 











Make a request to register a user through the "api/account/register" api.
Note:
Content type: application/json
Method: Post
Password length: Please refer to the min requirement set in "App_Start/IdentityConfig.cs"

































Next, back to VS's server explorer. This time, you shall see something within the database connection. Bingo!

























Make a request to "/Token" to get your access token. Once you have the token successfully returned from the Web API, then you are allowed to use the same access token for the subsequent access for rest of the the resources you wanted from the server. 
Login with the user you have just created.

Note:
Content type: application/x-www-form-urlencoded
Method: Post
QueryString pattern: username=xxxx&password=xxxx&grant_type=password































Continue... copy the token from the response:

















Yes! From here onward, you do not need to login (or call the "/token", except for expired) anymore.
Here is the example of how to use the access_token in your request. The request to ValuesController (/api/values) require access token. This is because it is marked with  [Authorize]  attribute in the class. 







































What if, without the Authorisation section in the header? 






































Conclusion

I'm currently a mobile team lead  + senior developer for a company. I used to heavily involved in web application development. I understand the market as well as the important of having web application. However, the demand of providing data service to portable device is getting more important and critical. A server side service should start serving the data to various type of clients.

Web API is something that I would recommended. If you are a mobile developer, you should at least give it a try, extend the mobile development architecture from standalone model to client server, and data service based model.


No comments:

Post a Comment

How to run unit test for your Xamarin Application in AppCenter?

How to run unit test for your Xamarin application in AppCenter?  When we talk about Building and Distributing your Xamarin app, you m...