Token Based Authentication
we’ll use token based approach to implement authentication between the front-end application and the back-end API, as we all know the common and old way to implement authentication is the cookie-based approach were the cookie is sent with each request from the client to the server, and on the server it is used to identify the authenticated user.
With the evolution of front-end frameworks and the huge change on how we build web applications nowadays the preferred approach to authenticate users is to use signed token as this token sent to the server with each request, some of the benefits for using this approach are:
- Scalability of Servers: The token sent to the server is self contained which holds all the user information needed for authentication, so adding more servers to your web farm is an easy task, there is no dependent on shared session stores.
- Loosely Coupling: Your front-end application is not coupled with specific authentication mechanism, the token is generated from the server and your API is built in a way to understand this token and do the authentication.
- Mobile Friendly: Cookies and browsers like each other, but storing cookies on native platforms (Android, iOS, Windows Phone) is not a trivial task, having standard way to authenticate users will simplify our life if we decided to consume the back-end API from native applications.
The OWIN project was started by the .NET community creating an abstraction between the web servers and the components of the Framework. The design of this abstraction has had two fundamental objectives, to create an abstraction as simple as possible and to use the minimum possible dependencies. All this helps us when creating new components, as it allows us to develop them more easily and are easier to use and integrate into other projects. This also gives us the ability to switch between different host servers or even have web applications hosted in our own process.
OWIN is a specification, i.e. a word. You have it at http://owin.org. Owin does NOT download, there is nothing executable that is OWIN. OWIN only tells you how to create OWIN components.
OWIN defines three types of basic components:
- Host: It is who “hosts” the whole infrastructure. Who sets up and initializes the rest of the components.
- Server: It receives the requests and generates the answers
- Middleware: The rest of OWIN components. They are modular components that are “chained” one after another. The request passes from one to another and each generates a part of the final answer (or whatever it is). We can have one OWIN component for security, another to do Log, and another to generate REST APIs. E.g. WebApi is an OWIN component. SignalR is another OWIN component. MVC does not (although theoretically could be).
OAuth is an open standard for access delegation, commonly used as a way for Internet users to grant websites or applications access to their information on other websites but without giving them the passwords. This mechanism is used by companies such as Google, Facebook, Microsoft and Twitter to permit the users to share information about their accounts with third party applications or websites.
Generally, OAuth provides to clients a “secure delegated access” to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.
The use case which will be covered in this application are:
- Prevent anonymous users from viewing secured data or secured pages (views).
- Once the user is logged in successfully, the system should not ask for credentials or re-authentication for the next 24 hours because we are using refresh tokens.
Building the Back-End API
- Create a Web API Project
In visual studio we have to create an empty Web API project and be sure that there is no authentication selected.
2. Installing the needed NuGet Packages
Using nuget package manager install the following packages:
- Microsoft.AspNet.Identity.Owin : add support for ASP.NET Identity Owin.
- Install-Package Microsoft.Owin.Security.Oauth: add OAuth authentication workflow
3. Add support for OAuth Bearer Tokens Generation
Open file “Startup” and implement the Configuration method as below:
Here we’ve created new instance from class “OAuthAuthorizationServerOptions” and set its option as the below:
- The path for generating tokens will be as :”http://localhost:port/token”. We’ll see how we will issue HTTP POST request to generate token in the next steps.
- We’ve specified the expiry for token to be 24 hours, so if the user tried to use the same token for authentication after 24 hours from the issue time, his request will be rejected and HTTP status code 401 is returned.
- We’ve specified the implementation on how to validate the credentials for users asking for tokens in custom class named “MyAuthorizationServerProvider”.
Now we passed this options to the extension method “UseOAuthAuthorizationServer” so we’ll add the authentication middleware to the pipeline.
4. Implement the “MyAuthorizationServerProvider” class
Add new class named “MyAuthorizationServerProvider”, paste the code snippet below:
As you notice this class inherits from class “OAuthAuthorizationServerProvider”, we’ve overridden two methods “ValidateClientAuthentication” and “GrantResourceOwnerCredentials”. The first method is responsible for validating the “Client”, in our case we have only one client so we’ll always return that its validated successfully.
The second method “GrantResourceOwnerCredentials” is responsible to validate the username and password sent to the authorization server’s token endpoint, so we’ll use a simple static check to verify that the username and password are valid.
If the credentials are valid we’ll create “ClaimsIdentity” class and pass the authentication type to it, in our case “bearer token”, then we’ll add two claims (”role”,”name”) and those will be included in the signed token. You can add different claims here but the token size will increase for sure.
Now generating the token happens behind the scenes when we call “context.Validated(identity)”.
5. Allow CORS for ASP.NET Web API
First of all we need to install the following NuGet package manger: Microsoft.Owin.Cors.
Now open class “Startup” again and add the line app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll); //enable cors origin request
6. Add Web API Controller
Lets add a controller where all the cases will be contained. Use the snipet below:
7. Testing Controller
Assuming that you registered the username “admin” with password “admin” in the step below, we’ll use the same username to generate token, so to test this out open your favorite REST client application in order to issue HTTP requests to generate token for user “admin”. For me I’ll be using PostMan.
Now we’ll issue a POST request to the endpoint http://localhost:12287/token the request will be as the image below:
Notice that the content-type and payload type is “x-www-form-urlencoded” so the payload body will be on form (grant_type=password&username=”Taiseer”&password=”SuperPass”). If all is correct you’ll notice that we’ve received signed token on the response.
As well the “grant_type” Indicates the type of grant being presented in exchange for an access token, in our case it is password.
Now we want to use this token to request the secure data using the end point http://localhost:12287/api/data/authenticate so we’ll issue GET request to the end point and will pass the bearer token in the Authorization header, so for any secure end point we’ve to pass this bearer token along with each request to authenticate the user.
Note: that we are not transferring the username/password as the case of Basic authentication.
The GET request will be as the image below:
If all is correct we’ll receive HTTP status 200 along with the secured data in the response body, if you try to change any character with signed token you directly receive HTTP status code 401 unauthorized.
Now our back-end API is ready to be consumed from any front end application or native mobile app.
You can find the code of this post HERE