Asp.Net Web API Token Based Authentication

Today i will try to explain how to use token based authendtication on asp.net web api 2 restful service projects. Restful service architecture very populer because it’s very light and implemantation is very easy.  Other big advantage of restful services is, it gives us a chance to service our data to all platforms including mobile devices, web projects, televisions etc.


You can see token based scenario implementation at below image

accessToken

So basicially authendtication steps are :

  • User sends creadentials to server
  • Authorization Server sends an access token if creadentials are correct
  • Users can reach other service methods with access token

 

Now its time to start sample project

We use OAuth 2.0  protocol and Microsoft Owin Library will help us. Owin is basically creating own pipeline between iis and application to manage requests.

I’ve created Asp.Net Web Application project with empty templates and Wep API core reference

project

 

We need to add Microsoft.AspNet.WebApi.Owin, Microsoft.Owin.Host.SystemWeb and Microsoft.Owin.Security.OAuth package on nuget package manager.

After this package i’ve created  folder as OAuth and i created startup.cs class with below code.

using TokenBasedAuth.OAuth.Providers;
using Microsoft.Owin;
using Microsoft.Owin.Security.OAuth;
using Owin;
using System;
using System.Web.Http;
[assembly: OwinStartup(typeof(TokenBasedAuth.OAuth.Startup))]
namespace TokenBasedAuth.OAuth
{
//We are using this class to start owin pipeline
    public class Startup
    {
        public void Configuration(IAppBuilder appBuilder)
        {
            HttpConfiguration httpConfiguration = new HttpConfiguration();

            ConfigureOAuth(appBuilder);

            WebApiConfig.Register(httpConfiguration);
            appBuilder.UseWebApi(httpConfiguration);
        }

        private void ConfigureOAuth(IAppBuilder appBuilder)
        {
            OAuthAuthorizationServerOptions oAuthAuthorizationServerOptions = new OAuthAuthorizationServerOptions()
            {
                TokenEndpointPath = new Microsoft.Owin.PathString("/token"), // token path
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                AllowInsecureHttp = true,
                Provider = new SimpleAuthorizationServerProvider()
            };

            // To create an access token on AppBuilder 
            appBuilder.UseOAuthAuthorizationServer(oAuthAuthorizationServerOptions);

            // We are setting Authentication type as a Bearer Authentication.
            appBuilder.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
        }
    }
}

Next step i’ve created Providers folder in OAuth folder and SimpleAuthorizationServerProvider.cs class inside of Providers folder with below codes.

using Microsoft.Owin.Security.OAuth;
using System.Threading.Tasks;
using System.Security.Claims;

namespace TokenBasedAuth.OAuth.Providers
{
    public class SimpleAuthorizationServerProvider : OAuthAuthorizationServerProvider
    {
        //Overriding to  OAuthAuthorizationServerProvider classes ValidateClientAuthentication method.
        public override async System.Threading.Tasks.Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            context.Validated();
        }
        //Overriding to  OAuthAuthorizationServerProvider classes GrantResourceOwnerCredentials method.
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            // CORS settings
            context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

            // Validation for user access
            if (context.UserName == "UserName" && context.Password == "Password")
            {
                var identity = new ClaimsIdentity(context.Options.AuthenticationType);
                identity.AddClaim(new Claim("sub", context.UserName));
                identity.AddClaim(new Claim("role", "user"));
                context.Validated(identity);
            }
            else
            {
                context.SetError("invalid_grant", "Username or password is incorrect");
            }
        }
    }
}

I just want to underline a point about above code and it’s about CORS settings.

   context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });

We are saying to owin with this code restful service allow to alldomains to all requests.Finally we are ready to use token based authendtication, lets create a product controller to test our authentication service.

ProductController.cs class codes are below

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace TokenBasedAuth.Controllers
{
    [Authorize]
    public class ProductController : ApiController
    {
        [HttpGet]
        public List<string> List()
        {
            List<string> products = new List<string>();

            products.Add("Product 1");
            products.Add("Product 2");
            products.Add("Product 3");
            products.Add("Product 4");
            products.Add("Product 5");

            return products;
        }
    }
}

 

 [Authorize]

This line says all methods of ProductController is need authentication.

When we run projects and navigate to /api/Product/List we will see below message on browser

<Error>
 <Message>Authorization has been denied for this request.</Message>
</Error>

To get a access token we have to send a request /token

with following parameters

Request headers :

Header: Accept                Value: application/json
Header: Content-Type     Value: application/x-www-form-urlencoded

Request Body :

Data-Type : x-www-form-urlencoded

Key: grant_type                 Value: password
Key: username                   Value:Username
Key: password                    Value: Password

You can find successfull postman request at below image

token

Now we are ready to new request with access token we need to add this headers to request
Header: Content-Type     Value: application/json

Header: Authorization     Value: Bearer accessTokenHere

productList

As you can see at above picture we got to product list with our secure access token. I hope this tutorial helps you.

You can find source code here : https://github.com/hamdiceylan/WebAPITokenBasedAuthentication

If you have any question about tutorial you can leave a comment.

 

 

 

 

Leave a Reply

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