Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web Api 2 with OWIN OAuth Bearer tokens

I'm in the process of building a web api in visual studio 2013 and want to authenticate using OWIN middleware and bearer tokens. However I already have a database and don't want to use Microsoft's new Identity framework as the majority of tables and columns that it auto generates I simply don't need.

Can anyone point me in the right direction of how to apply this type of authentication without having to use the Microsoft Identity framework?

like image 842
Tron Diggy Avatar asked Aug 12 '14 13:08

Tron Diggy


People also ask

How do I pass a bearer token in API?

Bearer tokens enable requests to authenticate using an access key, such as a JSON Web Token (JWT). The token is a text string, included in the request header. In the request Authorization tab, select Bearer Token from the Type dropdown list. In the Token field, enter your API key value.

What is the difference between OWIN and OAuth?

Katana is open-source components for building and hosting OWIN-based web applications. It provides the implementation of the OWIN specification. The OAuth authorization framework enables a third-party application to obtain limited access to a HTTP service.


2 Answers

My suggestion would be to use the framework but extend it to use your objects and infrastructure. I am currently in the middle of doing this and landed on this question. Here's how I've tackled it so far:

Step 1: Your own CustomUserObject

Write/Use your own "ApplicationUser" object. In the template project, you want to modify the "IdentityModels" file. It has ApplicationUser object defined in there. Assuming you already have all the properties from your existing app, you will need to add GenerateUserIdentityAsync() method but change the type of the parameter to UserManager manager). After the change, your method signature looks like this:

public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<CustomUserObject> manager)

Step 2: Define your own IUserStore<> implementation

Add a new class CustomUserStore that implements IUserStore, like so:

public class CustomUserStore : IUserStore<CustomUserObject>
{
    private readonly IUserManagerService _userManagerService;
    public CustomUserStore(IUserManagerService userManagerService)
    {
        _userManagerService = userManagerService
    }

    //implementation code for all of the IUserStore methods here using
    //userManagerService or your existing services/classes
}

I am using Unity to inject IUserManagementService's implementation above.

I have made use of the comprehensive UserManager class that comes with the Microsoft Identity framework but extended the framework to use my API for authentication and authorization. You could write your own UserManager but I found that it is pretty tedious and there is no reason why UserManager could work for most cases of Securing an app.

Step 3: Changes in the IdentityConfig.cs file

Change the class definition to make ApplicationUserManager class inherit from UserManager

You'll need to do the samething in the constructor of this class as well; i.e. have IUserStore. Modify the Create static method's first line to make use of the new store and a wrapper class that provides as a means to be a "DbContext" like so:

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var manager = new ApplicationUserManager(new ApplicationUserStore(context.Get<UserManagementServiceWrapper>()));
        //modify the relevant lines after this to suit your needs
        ...
    }

My UserManagementServiceWrapper looks like this (please note that I'm not too happy that it inherits from a concrete UserManagementService class that provides the methods to connect to the service that provides user data, I'm still building this out):

public class UserManagementServiceWrapper : UserManagementService, IDisposable
{
    public void Dispose()
    {
        throw new NotImplementedException();
    }
}

Step 4: Change the ApplicationDbContext class to return a UserManagementServiceWrapper instance

public class ApplicationDbContext : UserManagementServiceWrapper
{
    public static UserManagementServiceWrapper Create()
    {
        return new UserManagementServiceWrapper();
    }
}

And that is pretty much it. You still have to write the implementation for CustomUserStore object but everything should work.

Please note this is not boilerplate code and no where near "code review ready", as I said, I'm still digging deeper into this and building it out to use custom stores, data access objects, services etc. I thought you'll get a good start with some of the things that took me a couple of hours to figure out. I will blog about this when I have a good solution.

Hope this helps.

like image 66
amythn04 Avatar answered Oct 12 '22 17:10

amythn04


I prob. dont understand the question entirely but it looks like you are trying to do without the whole owin pipeline?

If not then..

You need to implement few interfaces related to users and roles described as below.

http://www.asp.net/identity/overview/extensibility/overview-of-custom-storage-providers-for-aspnet-identity

Have a look at the following post from Scott Allen

http://odetocode.com/blogs/scott/archive/2013/11/25/asp-net-core-identity.aspx

This way you can use your own tables, DAL and services to create UserManager and RoleManager objects.

Edit: Samples over here should give you some pointers.

Edit2: Custom User Store Example. IRepository is the object which takes care of CRUD.

    public class CustomUserStore : IUserStore<User>,....
    {
        private readonly IRepository _repository;
        public CustomUserStore(IRepository repository)
        {
            if (repository == null)
                throw new ArgumentNullException("repository");
            _repository = repository;
        }
        public Task CreateAsync(User user)
        {
            if (user == null) throw new ArgumentException("user");
            _repository.User.Add(user);
            return _repository.CommitAsync();
        }
...
like image 31
daehaai Avatar answered Oct 12 '22 17:10

daehaai