OAuth Web API token based authentication with custom database

web api token authentication example how to configure owin authentication using my existing users table custom application oauth provider owin authentication custom database owin database token based authentication using asp.net web api 2 owin and identity usermanagerfactory new usermanager identityuser new userstore identityuser use asp.net identity with existing database

Token base authentication with custom database by using OAuth in Web API is not complicated but documents are not very clear, many people try it and ended up with scratching their head, but you are on the right page so you will not be one of them.

We will not use any template code but we will start empty project with Web API, so all the authentication code we need to write, let's start a news project say "TokenAuth" or any other name you like:

  • New Project
  • ASP.Net Web Application (.Net Framework)
  • Select a folder and give the name and click OK
  • Select Empty from ASP.Net 4.5.x Templates
  • Choose Web API checkbox
  • Click Ok to create the project

Now we have a very basic project with some empty folders and some files like global.asax, web.config and WebApiConfig.cs in App_Start folder that's It.

Create empty web api project

Before start writing our code, rebuild the newly created project if It goes good, otherwise fix the issues first. Once it start working we need to install some packages, here is the list of packages which we need to use the OAuth, Owin. For it open the package manager console from the menu View => Other Windows => Package Manager Console and run following commands:

  • Install-package Microsoft.AspNet.WebApi.Owin
  • Install-Package Microsoft.Owin.Host.SystemWeb
  • Install-Package Microsoft.AspNet.Identity.Owin

We don't want to complicate the logic by adding entity framework or some other ORM to get the user detail to validate from database, rather we will create a User class and list of hardcoded users object and validate the user credential against this list, you can change this part to use from database for real project.

Models/User.cs: Let's create a user model say User in Models Folder

public class User
{
    public int Id { get; set; }
    public String Name { get; set; }
    public String Email { get; set; }
    public String Password { get; set; }
} 

Services/UserService.cs: Now we need a user service to get the data from database (say dummy record) and validate the user against provided email/user Id and password, so create a new service and add following code:

public class UserService
{
    public User ValidateUser(string email, string password)
    {
        // Here you can write the code to validate
        // User from database and return accordingly
        // To test we use dummy list here
        var userList = GetUserList();
        var user = userList.FirstOrDefault(x => x.Email == email && x.Password == password);
        return user;
    }

    public List<User> GetUserList()
    {
        // Create the list of user and return           
    }
} 

Till now we created our custom user model and user service to validate user by checking Id and passwords.

Startup.cs: Create a new file on the root, named Startup.cs and add following code in it, note it is a partial class:

using Owin;
namespace TokenAuth
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
    }
}

App_Start/Startup.cs: Create another class in app_start folder and make it also partial, two partial class will only merge if they will have the same namespace, so please make both the Startup.cs file have the same namespace, in my case it is TokenAuth

using Owin;
using System;
using Microsoft.Owin;
using TokenAuth.Providers;
using Microsoft.Owin.Security.OAuth;
namespace TokenAuth
{
    public partial class Startup
    {
        public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

        static Startup()
        {
            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/token"),
                Provider = new OAuthProvider(),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
                AllowInsecureHttp = true
            };
        }
        public void ConfigureAuth(IAppBuilder app)
        {
            app.UseOAuthBearerTokens(OAuthOptions);
        }
    }
}

Once you will copy the above code you will get error of OAuthProvider, because still we have not added this class.

Providers/OAuthProvider.cs: Create a new folder Providers and inside this folder add a new class OAuthProvider.cs and add following code in it:

using System;
using TokenAuth.Services;
using Microsoft.Owin.Security;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.Owin.Security.OAuth;

namespace TokenAuth.Providers
{
    public class OAuthProvider: OAuthAuthorizationServerProvider
    {
        #region[GrantResourceOwnerCredentials]
        public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            return Task.Factory.StartNew(() =>
            {
                var userName = context.UserName;
                var password = context.Password;
                var userService = new UserService(); // our created one
                var user = userService.ValidateUser(userName, password);
                if (user != null)
                {
                    var claims = new List<Claim>()
                    {
                        new Claim(ClaimTypes.Sid, Convert.ToString(user.Id)),
                        new Claim(ClaimTypes.Name, user.Name),
                        new Claim(ClaimTypes.Email, user.Email)
                    };
                    ClaimsIdentity oAuthIdentity = new ClaimsIdentity(claims,
                                Startup.OAuthOptions.AuthenticationType);

                    var properties = CreateProperties(user.Name);
                    var ticket = new AuthenticationTicket(oAuthIdentity, properties);
                    context.Validated(ticket);
                }
                else
                {
                    context.SetError("invalid_grant", "The user name or password is incorrect");
                }
            });
        }
        #endregion

        #region[ValidateClientAuthentication]
        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            if (context.ClientId == null)
                context.Validated();

            return Task.FromResult<object>(null);
        }
        #endregion

        #region[TokenEndpoint]
        public override Task TokenEndpoint(OAuthTokenEndpointContext context)
        {
            foreach (KeyValuePair<string, string> property in context.Properties.Dictionary)
            {
                context.AdditionalResponseParameters.Add(property.Key, property.Value);
            }

            return Task.FromResult<object>(null);
        }
        #endregion

        #region[CreateProperties]
        public static AuthenticationProperties CreateProperties(string userName)
        {
            IDictionary<string, string> data = new Dictionary<string, string>
            {
                { "userName", userName }
            };
            return new AuthenticationProperties(data);
        }
        #endregion
    }
}

Get Token by providing Id, password and grant type

Let's crate a new Web API 2 Controller - Empty controller and put the Authorize attribute on it so any method in it can only be accessed by Authorized users, means who is passing the Authorized bearer token in header, give it is name AccountController.cs:

[Authorize]
public class AccountController : ApiController
{
    [HttpGet]
    [Route("api/account/getuser/{id}")]
    public IHttpActionResult GetUFirstUser(int id)
    {
        // Get user from dummy list
        var user = userList.FirstOrDefault(x => x.Id == id);
        return Ok(user);
    }
}

See how to call the authorized method by using authorization and bearer token, I use postman to test the feature

Get Token by providing Id, password and grant type

If you want to use your service from some other domain or using from Angular we will get the CORS error, to resolve the CORS error we need one more package:

Install-package Microsoft.Owin.Cors

After installing it change the code in Startup.cs file on the root to:

public void Configuration(IAppBuilder app)
{
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    ConfigureAuth(app);           
}

In next article we will try to use this Web API with token base authentication in an Angular 4 application and we will see how we can active roots after successful authorization, till then enjoy....

Ali Adravi Having 13+ years of experience in Microsoft Technologies (C#, ASP.Net, MVC and SQL Server). Worked with Metaoption LLC, for more than 9 years and still with the same company. Always ready to learn new technologies and tricks.
  • oauth
  • web-api
By Ali Adravi On 11 Sep, 17  Viewed: 204

Other blogs you may like

Angular 4 upload files with data and web api by drag & drop

Upload file with data by clicking on button or by drag and drop, is the topic of this article. We will try to create an image gallery by uploading files and save data into database and images into a folder. We will try to create a component in a way that it can be used anywhere in entire... By Ali Adravi   On 24 Sep 2017  Viewed: 638

What is ASP.Net Web API, why & when to use

What is ASP.Net Web API, what is RESTFul service, What is the difference between WCF and Web API and when to use over other. These are the main points which we going to discuss in this starting article, then we will create our own Web API project and look each and every single type of methods... By Ali Adravi   On 13 Jul 2017  Viewed: 610

Angularjs ui-routing with Web API

I found most of .Net developer whether they are ASP.Net developer or MVC developer, they face to start and how to create the Angularjs application structure. In this article we will start from an empty project with Web API 2.0. First of all we will create very simple application with three... By Ali Adravi   On 18 Jul 2015  Viewed: 2,858