Web API token authentication with a custom user database
Asked Answered
A

5

64

I am developing a Web API 2.1 service that needs to authenticate the connecting clients (HTML5/JS clients that I will create and control). Unfortunately, the user information (username, password hashes, roles and much, much more info) is stored in an existing (SQL Server) database to which I only have read access. The Users database table was created 5-6 years ago without any reference to security frameworks, so it's a completely custom format. I'm not allowed to make any changes to either the data or the database structure.

Inspired by this article, I rolled my own token-based method of authenticating users, but I'm lacking the completeness and (re)assurance of using an established security framework.

Is there a way to integrate an existing framework, e.g. OAuth2, within my current project given the constraints I mentioned above? I don't know if it makes any difference, but I'm self-hosting using OWIN.

Awad answered 18/6, 2014 at 23:32 Comment(3)
I'm looking into a similar issue - existing API tokens are in the DB that I need to work with. Currently I see 2 options: 1) A HTTP module or message handler that intercepts tokens and sorts out the current principal (basic auth-like). 2) Hacking around with the ASP.NET Identity bearer token to see if I can get that working with custom tokens.... Not sure which to go with yet :)Shiner
Can you store session details in a separate database/table?Jerrome
Valid question, I wish someone had a good answer. Integrating into legacy systems is a common situation that seems to be frequently ignored.Radical
K
19

This is a good answer to a similar question. It basically says:

  • Make a custom user class which implements IUser
  • Define a custom user store which implements public class UserStoreService : IUserStore<CustomUser>, IUserPasswordStore<CustomUser>
  • wire everything up

Since the answer is pretty extensive I just provided the basic steps... details are here: How to customize authentication to my own set of tables in asp.net web api 2?

This is also a very valuable content which also applies to web api:

Customizing ASP.NET Authentication with Identity by JumpStart

https://channel9.msdn.com/Series/Customizing-ASPNET-Authentication-with-Identity

HTH

Kithara answered 15/2, 2015 at 13:38 Comment(2)
YouTube video link is dead.Belostok
Any example? This link is dead.Garnet
D
2

Someone else, having the competence, can explain the options. But if authentication as service is an option, then check out Auth0 @ https://auth0.com

I have tested the service (as Azure plugin) using both HTML/JS- and native Windows Phone applications, against simple Sql Server table and AD. Works liek charm, near zero headache.

Doall answered 19/6, 2014 at 20:56 Comment(2)
Thanks for the response. Unfortunately, authentication as a service is not an option for us, as we want to keep everything in-house. Having to integrate with our internal legacy, custom system is a pain, but I have no choice on that.Awad
I have been looking at Auth0 and it looks good, but I don't see how to connect the Auth0 login to an existing SQL Server database of existing users. Can you shed any light on that? (this is in a pure Angular2 environment, no ASP.Net MVC).Megaspore
U
2

I stumbled upon a my solution while trying to implement json token authentication within web api. It is important to note that my solution handles authentication by sending a json token through the Authentication header of the Http request (not via cookies) and not using Microsoft.Identity framework.

Anyway, I basically implemented in a cookbook fashion the solution helpfully described here by Taiseer Joudeh: http://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/

The key thing to notice is the following bit of code:

//Dummy check here, you need to do your DB checks against memebrship system http://bit.ly/SPAAuthCode
        if (context.UserName != context.Password)
        {
            context.SetError("invalid_grant", "The user name or password is incorrect");
            //return;
            return Task.FromResult<object>(null);
        }

Naturally you would replace this bit of code above with your own method for checking your (presumably pre-existing) user database(s). Once I implemented this I realized that you don't need to use new code first identity framework that Visual Studio installs for you.

To make this work I did the following:

1) Created an an empty project and selected Change Authentication/Individual User Accounts. This installs most of the required references and files you need out of the box to use token authentication by way of cookies as well as the code-first identity framework files.

2) Edited these files following Taiseer Joudeh's lead. This requires some new objects such as CustomOAuthProvider.cs among others. And you need to implement your own user/password check by customizing this code block:

if (context.UserName != context.Password) { context.SetError("invalid_grant", "The user name or password is incorrect"); //return; return Task.FromResult<object>(null); }

Link to Taiseer Joudeh's instructions: http://bitoftech.net/2014/10/27/json-web-token-asp-net-web-api-2-jwt-owin-authorization-server/

3) Pruned my project of extraneous files (AccountBindingModels.cs, AccountViewModels.cs, IdentityModels.cs, ApplicationOAuthProvider.cs, identityConfig.cs, AccountBindingModels.cs, AccountViewModels.cs). Basically, No more microsoft identity references.

I am sure the microsoft.identity thing is excellent, but I was annoyed with the code-first implementation of databases when I was already using some legacy databases of a different structure etc. Hope this helps. I am quite satisfied with the result (after a few days of messing around to get it to work).

Unwelcome answered 16/7, 2015 at 21:51 Comment(0)
E
2

I did not want to use any existing classes and finally come out some thing very simple like

var userName = context.UserName;
var password = context.Password;
var userService = new UserService(); // our created one
var user = userService.ValidateUser(userName, password);
if (user != null){
   .......
}

See the full details here OAuth Web API token base authentication with custom database

For Role base authentication with custom database Hope it will help

Eatton answered 11/9, 2017 at 16:17 Comment(0)
S
1

This might be a completely insane and invalid approach for you but I faced a similar challenge: New web app (MVVM + WebAPI), legacy system used to issue and validate tokens. Inspired by http://tech.pro/tutorial/1216/implementing-custom-authentication-for-aspnet, and because my application would primarily be used by its accompanied GUI (the MVVM webapp), I decided to use a "cookie based" token produced by FormsAuthentication. The FormsAutnentication cookie/ticket is secured by .net internal magic security (which I assume id completely safe and unbreakable).

In my case the cookie simply holds the ticket issued by the legacy system, (but you could store more details there as well, eg by JSONSerializing a custom type). During authorization, my system validates the token against the legacy system. I guess you could use something similar together with a custom AuthorizationFilter.

Subsidiary answered 29/4, 2015 at 14:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.