.NET

Implement an OAuth 2.0 Authorization Server using OWIN OAuth middleware on ASP.NET web API.

This post is a beginner’s guide to setting up a ASP.NET web API project with OAuth 2.0 Authentication. You can follow the simple steps on youtube.

You can download a sample project on my gihub.

In Visual Studio, create a new ASP.NET Web project, select Empty and add folder and core references for Web API.

owin1

We need 3 additional packages from NuGet to set this project up:

Microsoft.AspNet.WebApi.Owin
Microsoft.Owin.Host.SystemWeb
Microsoft ASP.NET Identity Owin

Here is my package.config:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net452" />
  <package id="Microsoft.AspNet.Identity.Owin" version="2.2.1" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net452" />
  <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.1" targetFramework="net452" />
  <package id="Microsoft.Net.Compilers" version="1.3.2" targetFramework="net452" developmentDependency="true" />
  <package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net452" />
  <package id="Microsoft.Owin.Security" version="2.1.0" targetFramework="net452" />
  <package id="Microsoft.Owin.Security.Cookies" version="2.1.0" targetFramework="net452" />
  <package id="Microsoft.Owin.Security.OAuth" version="2.1.0" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
  <package id="Owin" version="1.0" targetFramework="net452" />
</packages>

 

Files to add to the project:

owin2

Now we will need a user class and a service to simulate a database with user credentials.

Models/User.cs

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

 

Service/UserService.cs

In this service you will need to hook up you user database and so on.

public class UserService
    {
        public User GetUserByCredentials(string email, string password)
        {
            User user = new User() { Id = "1", Email = "email@domain.com", Password = "password", Name = "Ole Petter Dahlmann" };
            if (user != null)
            {
                user.Password = string.Empty;
            }
            return user;
        }
    }

 

Next step is to set up your OAuth Authorization Server Provider.

Provier/OAuthAppProvider.cs

public class OAuthAppProvider : OAuthAuthorizationServerProvider
    {
        public override Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            return Task.Factory.StartNew(() =>
            {
                var username = context.UserName;
                var password = context.Password;
                var userService = new UserService();
                User user = userService.GetUserByCredentials(username, password);
                if (user != null)
                {
                    var claims = new List<Claim>()
                    {
                        new Claim(ClaimTypes.Name, user.Name),
                        new Claim("UserID", user.Id)
                    };

                    ClaimsIdentity oAutIdentity = new ClaimsIdentity(claims, Startup.OAuthOptions.AuthenticationType);
                    context.Validated(new AuthenticationTicket(oAutIdentity, new AuthenticationProperties() { }));
                }
                else
                {
                    context.SetError("invalid_grant", "Error");
                }
            });
        }

        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            if (context.ClientId == null)
            {
                context.Validated();
            }
            return Task.FromResult<object>(null);
        }
    }

 

Create a partial Startup class in the root of your project:

Startup.cs

public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
    }

 

Then create the configuration for this file in your App_Start folder:

App_Start/Startup.Auth.cs

public partial class Startup
    {
        public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }

        static Startup()
        {
            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/token"),
                Provider = new OAuthAppProvider(),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(2),
                AllowInsecureHttp = true
            };
        }

        public void ConfigureAuth(IAppBuilder app)
        {
            app.UseOAuthBearerTokens(OAuthOptions);
        }
    }
}

Now you are good to go, the only thing we need now is an extension for OWIN to get the user from the OwinContext claims.

Extentions/OwinContextExtentions.cs

public static class OwinContextExtensions
    {
        public static string GetUserId(this IOwinContext ctx)
        {
            var result = "-1";
            var claim = ctx.Authentication.User.Claims.FirstOrDefault(c => c.Type == "UserID");
            if (claim != null)
            {
                result = claim.Value;
            }
            return result;
        }
    }

 

 

Thanks for reading