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.
It is not required to create an empty project and only then you can implement it, you can create a Web API Application and add the code provided in this article. I used an empty Web API project to show that nothing is hidden and complicated just two three small functions and you will be done.
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:
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.
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:
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
}
}
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
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);
}
For Role Base Authentication with Web API 2 and Bearer token, just extended this article with some minor changes hardly 2 to 3 lines and see the working examples.
In next article we will try to use this Web API with token base authentication in an Angular 6 application and we will see how we can activate roots after successful authorization, till then enjoy....
Angular 6 Web API 2 Bearer Token Authentication add to header with HttpInterceptor
![]() |
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.
|
By Ali Adravi On 11 Sep, 17 Viewed: 17,479 |
Create Token with user credential & roles and authorize action methods based on role in Web API is the topic we will cover in this article. We would need to pass token in every request and decorate action methods with [Authorize(Roles = "Admin, Manager") etc. that's only the code we will need to... By Ali Adravi On 04 Oct 2018 Viewed: 6,455
Token base authentication expires over a fixed time, to overcome on it we need to use the refresh token. We will try to create the token as well as the refresh token after successful login, refresh token will be used to generate a new token if current token is already expired and it is not too... By Ali Adravi On 08 Oct 2018 Viewed: 17,054
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: 40,971
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: 1,367
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: 3,817