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.
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:
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