Token Based Authentication using ASP.NET Web API 2, Owin, and Identity

Last week I was looking at the top viewed posts on my blog and I noticed that visitors are interested in the authentication part of ASP.NET Web API, CORS Support, and how to authenticate users in single page applications built with AngularJS using token based approach.

So I decided to compile mini tutorial of three five posts which covers and connects those topics. In this tutorial we’ll build SPA using AngularJS for the front-end, and ASP.NET Web API 2, Owin middleware, and ASP.NET Identity for the back-end.


The demo application can be accessed on (http://ngAuthenticationWeb.azurewebsites.net). The back-end API can be accessed on (http://ngAuthenticationAPI.azurewebsites.net/) and both are hosted on Microsoft Azure, for learning purposes feel free to integrate and play with the back-end API with your front-end application. The API supports CORS and accepts HTTP calls from any origin. You can check the source code for this tutorial on Github.

AngularJS Authentication

 

Token Based Authentication

As I stated before we’ll use token based approach to implement authentication between the front-end application and the back-end API, as we all know the common and old way to implement authentication is the cookie-based approach were the cookie is sent with each request from the client to the server, and on the server it is used to identify the authenticated user.

With the evolution of front-end frameworks and the huge change on how we build web applications nowadays the preferred approach to authenticate users is to use signed token as this token sent to the server with each request, some of the benefits for using this approach are:

  • Scalability of Servers: The token sent to the server is self contained which holds all the user information needed for authentication, so adding more servers to your web farm is an easy task, there is no dependent on shared session stores.
  • Loosely Coupling: Your front-end application is not coupled with specific authentication mechanism, the token is generated from the server and your API is built in a way to understand this token and do the authentication.
  • Mobile Friendly: Cookies and browsers like each other, but storing cookies on native platforms (Android, iOS, Windows Phone) is not a trivial task, having standard way to authenticate users will simplify our life if we decided to consume the back-end API from native applications.

What we’ll build in this tutorial?

The front-end SPA will be built using HTML5, AngularJS, and Twitter Bootstrap. The back-end server will be built using ASP.NET Web API 2 on top of Owin middleware not directly on top of ASP.NET; the reason for doing so that we’ll configure the server to issue OAuth bearer token authentication using Owin middleware too, so setting up everything on the same pipeline is better approach. In addition to this we’ll use ASP.NET Identity system which is built on top of Owin middleware and we’ll use it to register new users and validate their credentials before generating the tokens.

As I mentioned before our back-end API should accept request coming from any origin, not only our front-end, so we’ll be enabling CORS (Cross Origin Resource Sharing) in Web API as well for the OAuth bearer token provider.

Use cases which will be covered in this application:

  • Allow users to signup (register) by providing username and password then store credentials in secure medium.
  • Prevent anonymous users from viewing secured data or secured pages (views).
  • Once the user is logged in successfully, the system should not ask for credentials or re-authentication for the next 24 hours 30 minutes because we are using refresh tokens.

So in this post we’ll cover step by step how to build the back-end API, and on the next post we’ll cover how we’ll build and integrate the SPA with the API.

Enough theories let’s get our hands dirty and start implementing the API!

Building the Back-End API

Step 1: Creating the Web API Project

In this tutorial I’m using Visual Studio 2013 and .Net framework 4.5, you can follow along using Visual Studio 2012 but you need to install Web Tools 2013.1 for VS 2012 by visiting this link.

Now create an empty solution and name it “AngularJSAuthentication” then add new ASP.NET Web application named “AngularJSAuthentication.API”, the selected template for project will be as the image below. Notice that the authentication is set to “No Authentication” taking into consideration that we’ll add this manually.

Web API Project Template

Step 2: Installing the needed NuGet Packages:

Now we need to install the NuGet packages which are needed to setup our Owin server and configure ASP.NET Web API to be hosted within an Owin server, so open NuGet Package Manger Console and type the below:

The  package “Microsoft.Owin.Host.SystemWeb” is used to enable our Owin server to run our API on IIS using ASP.NET request pipeline as eventually we’ll host this API on Microsoft Azure Websites which uses IIS.

Step 3: Add Owin “Startup” Class

Right click on your project then add new class named “Startup”. We’ll visit this class many times and modify it, for now it will contain the code below:

What we’ve implemented above is simple, this class will be fired once our server starts, notice the “assembly” attribute which states which class to fire on start-up. The “Configuration” method accepts parameter of type “IAppBuilder” this parameter will be supplied by the host at run-time. This “app” parameter is an interface which will be used to compose the application for our Owin server.

The “HttpConfiguration” object is used to configure API routes, so we’ll pass this object to method “Register” in “WebApiConfig” class.

Lastly, we’ll pass the “config” object to the extension method “UseWebApi” which will be responsible to wire up ASP.NET Web API to our Owin server pipeline.

Usually the class “WebApiConfig” exists with the templates we’ve selected, if it doesn’t exist then add it under the folder “App_Start”. Below is the code inside it:

Step 4: Delete Global.asax Class

No need to use this class and fire up the Application_Start event after we’ve configured our “Startup” class so feel free to delete it.

Step 5: Add the ASP.NET Identity System

After we’ve configured the Web API, it is time to add the needed NuGet packages to add support for registering and validating user credentials, so open package manager console and add the below NuGet packages:

The first package will add support for ASP.NET Identity Owin, and the second package will add support for using ASP.NET Identity with Entity Framework so we can save users to SQL Server database.

Now we need to add Database context class which will be responsible to communicate with our database, so add new class and name it “AuthContext” then paste the code snippet below:

As you can see this class inherits from “IdentityDbContext” class, you can think about this class as special version of the traditional “DbContext” Class, it will provide all of the Entity Framework code-first mapping and DbSet properties needed to manage the identity tables in SQL Server. You can read more about this class on Scott Allen Blog.

Now we want to add “UserModel” which contains the properties needed to be sent once we register a user, this model is POCO class with some data annotations attributes used for the sake of validating the registration payload request. So under “Models” folder add new class named “UserModel” and paste the code below:

Now we need to add new connection string named “AuthContext” in our Web.Config class, so open you web.config and add the below section:

Step 6: Add Repository class to support ASP.NET Identity System

Now we want to implement two methods needed in our application which they are: “RegisterUser” and “FindUser”, so add new class named “AuthRepository” and paste the code snippet below:

What we’ve implemented above is the following: we are depending on the “UserManager” that provides the domain logic for working with user information. The “UserManager” knows when to hash a password, how and when to validate a user, and how to manage claims. You can read more about ASP.NET Identity System.

Step 7: Add our “Account” Controller

Now it is the time to add our first Web API controller which will be used to register new users, so under file “Controllers” add Empty Web API 2 Controller named “AccountController” and paste the code below:

By looking at the “Register” method you will notice that we’ve configured the endpoint for this method to be “/api/account/register” so any user wants to register into our system must issue HTTP POST request to this URI and the pay load for this request will contain the JSON object as below:

Now you can run your application and issue HTTP POST request to your local URI: “http://localhost:port/api/account/register” or you can try the published API using this end point: http://ngauthenticationapi.azurewebsites.net/api/account/register if all went fine you will receive HTTP status code 200 and the database specified in connection string will be created automatically and the user will be inserted into table “dbo.AspNetUsers”.

Note: It is very important to send this POST request over HTTPS so the sensitive information get encrypted between the client and the server.

The “GetErrorResult” method is just a helper method which is used to validate the “UserModel” and return the correct HTTP status code if the input data is invalid.

Step 8: Add Secured Orders Controller

Now we want to add another controller to serve our Orders, we’ll assume that this controller will return orders only for Authenticated users, to keep things simple we’ll return static data. So add new controller named “OrdersController” under “Controllers” folder and paste the code below:

Notice how we added the “Authorize” attribute on the method “Get” so if you tried to issue HTTP GET request to the end point “http://localhost:port/api/orders” you will receive HTTP status code 401 unauthorized because the request you send till this moment doesn’t contain valid authorization header. You can check this using this end point: http://ngauthenticationapi.azurewebsites.net/api/orders

Step 9: Add support for OAuth Bearer Tokens Generation

Till this moment we didn’t configure our API to use OAuth authentication workflow, to do so open package manager console and install the following NuGet package:

After you install this package open file “Startup” again and call the new method named “ConfigureOAuth” as the first line inside the method “Configuration”, the implemntation for this method as below:

Here we’ve created new instance from class “OAuthAuthorizationServerOptions” and set its option as the below:

  • The path for generating tokens will be as :”http://localhost:port/token”. We’ll see how we will issue HTTP POST request to generate token in the next steps.
  • We’ve specified the expiry for token to be 24 hours, so if the user tried to use the same token for authentication after 24 hours from the issue time, his request will be rejected and HTTP status code 401 is returned.
  • We’ve specified the implementation on how to validate the credentials for users asking for tokens in custom class named “SimpleAuthorizationServerProvider”.

Now we passed this options to the extension method “UseOAuthAuthorizationServer” so we’ll add the authentication middleware to the pipeline.

Step 10: Implement the “SimpleAuthorizationServerProvider” class

Add new folder named “Providers” then add new class named “SimpleAuthorizationServerProvider”, paste the code snippet below:

As you notice this class inherits from class “OAuthAuthorizationServerProvider”, we’ve overridden two methods “ValidateClientAuthentication” and “GrantResourceOwnerCredentials”. The first method is responsible for validating the “Client”, in our case we have only one client so we’ll always return that its validated successfully.

The second method “GrantResourceOwnerCredentials” is responsible to validate the username and password sent to the authorization server’s token endpoint, so we’ll use the “AuthRepository” class we created earlier and call the method “FindUser” to check if the username and password are valid.

If the credentials are valid we’ll create “ClaimsIdentity” class and pass the authentication type to it, in our case “bearer token”, then we’ll add two claims (“sub”,”role”) and those will be included in the signed token. You can add different claims here but the token size will increase for sure.

Now generating the token happens behind the scenes when we call “context.Validated(identity)”.

To allow CORS on the token middleware provider we need to add the header “Access-Control-Allow-Origin” to Owin context, if you forget this, generating the token will fail when you try to call it from your browser. Not that this allows CORS for token middleware provider not for ASP.NET Web API which we’ll add on the next step.

Step 11: Allow CORS for ASP.NET Web API

First of all we need to install the following NuGet package manger, so open package manager console and type:

Now open class “Startup” again and add the highlighted line of code (line 8) to the method “Configuration” as the below:

Step 12: Testing the Back-end API

Assuming that you registered the username “Taiseer” with password “SuperPass” in the step below, we’ll use the same username to generate token, so to test this out open your favorite REST client application in order to issue HTTP requests to generate token for user “Taiseer”. For me I’ll be using PostMan.

Now we’ll issue a POST request to the endpoint http://ngauthenticationapi.azurewebsites.net/token the request will be as the image below:

OAuth Token Request

Notice that the content-type and payload type is “x-www-form-urlencoded” so the payload body will be on form (grant_type=password&username=”Taiseer”&password=”SuperPass”). If all is correct you’ll notice that we’ve received signed token on the response.

As well the “grant_type” Indicates the type of grant being presented in exchange for an access token, in our case it is password.

Now we want to use this token to request the secure data using the end point http://ngauthenticationapi.azurewebsites.net/api/orders so we’ll issue GET request to the end point and will pass the bearer token in the Authorization header, so for any secure end point we’ve to pass this bearer token along with each request to authenticate the user.

Note: that we are not transferring the username/password as the case of Basic authentication.

The GET request will be as the image below:

Token Get Secure Resource

If all is correct we’ll receive HTTP status 200 along with the secured data in the response body, if you try to change any character with signed token you directly receive HTTP status code 401 unauthorized.

Now our back-end API is ready to be consumed from any front end application or native mobile app.

Update (2014-08-11) Thanks for Attila Hajdrik for forking my repo and updating it to use MongoDb instead of Entity Framework, you can check it here.

You can check the demo application, play with the back-end API for learning purposes (http://ngauthenticationapi.azurewebsites.net), and check the source code on Github.

Follow me on Twitter @tjoudeh

References

Comments

  1. Kal Wolfson says

    Hi Taiser

    Sadly I have followed your tutorial to the T. And nothing seems to work. I’m not using SQL Express just SQL2008R2 so my connection string is

    ” Instead of

    But everything else is a carbon copy of what you have done.

    I’m using Postman for the requests

    When I post both “http://localhost:1587/api/account/register” or “http://ngauthenticationapi.azurewebsites.net/api/account/register” I get status code of “500 internal Server Error”

    When I issue a POST request to the endpoint “http://ngauthenticationapi.azurewebsites.net/token” I get a status code of “400 Bad Request” with a message of “{“error”:”unsupported_grant_type”}”.

    When I do a GET Request for “http://ngauthenticationapi.azurewebsites.net/api/orders” I get a status code of”401 Unorthorized” with a message of “{“message”:”Authorization has been denied for this request.”}”

    My Startup.cs is

    [assembly:OwinStartup(typeof(AngularJSAuthentication.API.Startup))]
    namespace AngularJSAuthentication.API
    {
    public class Startup
    {
    public void Configuration(IAppBuilder app)
    {
    var config = new HttpConfiguration();

    ConfigureOAuth(app);

    app.UseOAuthAuthorizationServer(OAuthServerOptions);
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    WebApiConfig.Register(config);
    app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
    app.UseWebApi(config);

    }

    public void ConfigureOAuth(IAppBuilder app)
    {
    var OAuthServerOptions = new OAuthAuthorizationServerOptions()
    {
    AllowInsecureHttp = true,
    TokenEndpointPath = new PathString(“/token”),
    AccessTokenExpireTimeSpan = TimeSpan.FromDays(1),
    Provider = new SimpleAuthorizationServerProvider()
    };

    // Token Generation
    app.UseOAuthAuthorizationServer(OAuthServerOptions);
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    }

    public OAuthAuthorizationServerOptions OAuthServerOptions { get; set; }
    }
    }

    Please help me find the problem?
    I fear I might lose my job if I cant get these things working.

  2. says

    Does the approach mentioned in the article, makes it to meets the requirements HIPAA compliance? Since the web server, I’m building is going to store medical and health information, that’s why I’m looking for the best security approach to secure the web services, which will be consumed by native Android and iOS apps.

    • says

      Hi Victor, I have replied you by email. Let me know if you need further details.
      I will paste my answer here too for other users:

      Regarding the HIPAA compliance, you need to Google this more as I can’t guarantee this, I was looking at this post and it looks OAuth 2.0 is complaint.

      Now the grant I’m using in my post is called “Resource owner password credential flow” and you need to make sure that you have full control on the source code written for the mobile application, in other words its very trusted mobile application that you are going to build or trusted third party will build it for you, think of it like the Official Twitter or Facebook application that you install it on your mobile and you present the Username/password in a native UI from the application, because if you do not trust this application you will not know how the App developer will use those credentials, maybe he will be evil enough to send them to another endpoint and harvest all your username/credentials.

      Now if this is not the case you need to use the Implicit flow or Authorization code flow where the user enters his credentials in Web page provided by the Authorization Server so the mobile application never sees the credentials and just receive an access token.

      For such critical application you are building, I recommend you to check as well the Regarding the HIPAA compliance, you need to Google this more as I can’t guarantee this, I was looking at this post and it looks OAuth 2.0 is complaint.

      Now the grant I’m using in my post is called “Resource owner password credential flow” and you need to make sure that you have full control on the source code written for the mobile application, in other words its very trusted mobile application that you are going to build or trusted third party will build it for you, think of it like the Official Twitter or Facebook application that you install it on your mobile and you present the Username/password in a native UI from the application, because if you do not trust this application you will not know how the App developer will use those credentials, maybe he will be evil enough to send them to another endpoint and harvest all your username/credentials.

      Now if this is not the case you need to use the Implicit flow or Authorization code flow where the user enters his credentials in Web page provided by the Authorization Server so the mobile application never sees the credentials and just receive an access token.

      For such critical application you are building, I recommend you to check as well the ThinkTecture Identity Server

  3. says

    Is there any way to get the value of the generated token before I send it to the client? I’m trying to build a routine to revoke the access token, but I don’t the complexity of use Refresh Tokens (and here we don’t use asp.net Identity)

  4. Juan says

    Hello Taiseer,

    First of all, a HUGE THANKS for your posts. So helpful! This is exactly what the development world is moving to, and you’re out there, way ahead, pushing it forward.

    I have a question: what is the best approach to hook user authentication to already-existing tables in SQL Server?. I would guess that most developers working on real-life applications will have a large number of tables already defined and will never allow any tables, like dbo.AspNetUsers, to be created or used in a production environment.

    Any suggestions or links to examples would greatly appreciated!

    Thanks again for your advice!

    Juan

  5. says

    Can/should an authorization token be reused, even after logging out?

    I notice that if I logout, then use Fiddler and resend a previous GetOrders request, using an old Authorization header, it still works.

    • says

      Hi Andrew,
      The tokens I’m using in the post called self contained tokens, and they are not revocable, once the server issue them they keep working until they expired, same applies to JWT tokens, if you need to implement some sort of logout on the server, then you have to use reference tokens.

  6. rahuljujarey says

    Hi Taiseer,

    Thanks for a great article.

    I have followed till Step 8, after that when I try to access api/Orders I am not getting 401 Unaithorized Error.

    Any ideas would be great, I have googled it a lot.

    Thanks,
    Rahul J

      • rahuljujarey says

        Hi,

        I was — not getting — 401 error when accessing without a bearer token.

        Figured out that Windows Authentication was enabled. I disabled WIndows Auth and enabled Anonymous Auth and it did worked.

        Thank you so much.

  7. says

    I needed to add **HostAuthenticationAttribute** filter before **AuthorizeFilter** to make your post work…

    config.Filters.Add(new HostAuthenticationAttribute(“bearer”));
    config.Filters.Add(new AuthorizeAttribute());

    I had copied your SimpleAuthorizationServerProvider.cs as it.. can you point out to me why I have to add the HostAuthenticationAttribute??

  8. Xavier says

    Hey Taiseer,

    I’m using your blogpost as a basis in one of my projects but I’m having some problems:

    I’m accessing the currently logged in user in a Controller through HttpContext.Current.User.Identity.GetUserId(). This works the first time I log in. However, when I log off in my application and log in with another user the value in HttpContext.Current.User.Identity.GetUserId() is not updated even though my claims are being updated to the correct values in GrantResourceOwnerCredentials.

    Do you have any idea on why this is happening and how to resolve this?

    • says

      How do you logout? You can’t logout with self contained tokens? If you are setting the claims correctly of type ClaimsType.Name then it should work fine. Anyhow let me know if you fixed this in another way?

      • Xavier says

        Well, I created an application that uses WCF RIA Service authentication. The user is able to log in and out of this application. However, I have another application that uses the self contained tokens. The user is able to log into the first application and then navigate to the second application. If he does that, I wanted the user to automatically be logged in to the second application as well. To do that, I used the self contained tokens on top of the RIA Service authentication in the first application so I could pass on the token to the second application while keeping my original code as well.

        Your comment made me realize that the two systems might conflict so I tried removing the RIA Service authentication and sure enough, it now works like a charm.

        Thanks for the help!

  9. Mario Galeano says

    Hi. I´m building a website that uses Azure AD to authenticate. I´m using angular, adal.js, adal-angular.js and Restangular. I have another site with a asp.net Web API with one controller with [Authorize]. But when I send an Get with the token I get “Authorization has been denied for this request.” What can I do?

    • says

      What do you mean by another Web Api? You have 2 web APIs? One for the SPA and other for different needs? If this the case then you need to configure the other Api to read tokens issued from Azure AD by using the same client Id and secret used for the Api used in the SPA app.

  10. Cristian says

    Hello, but at what point are the select a database? in my case I will not use entity framework but can not find where the query is made to guide me from there.

  11. Atul says

    Hi Taiseer,

    I am just curious to know that how would you handle Bearer token expiration in web api. My test case is as folowing

    1. you assign 10 sec to AccessTokenExpireTimeSpan (for testing only)
    2. Login in to website.
    3. Make one get or post call to controller(works fine)
    4. Make same call again after wait of 10 secs application will send the 404 error becuase Bearer token was present in header, therefore no 400 error, but it was expired and that is why 404.
    5. Solution I tried before making any get or post request check for expire time on front end and if it is expired get new one on the basis of refresh token.
    6. But what I would like to do is handle this error in web api and send new auth token and refresh token to front end.

    Is it possible??

    Regards,
    Atul Chaudhary(Big fan)

    • says

      Hi Atul,
      Thanks fir your message, well if you send an expired access token to API, it will return 401 unauthorized not 404 not found.

      And for your question in point 6, no it is not possible to do this, if you received 401, you need to try to get an access token using the refresh token, if it worked then you are in good shape, you have new access token and new refresh token id. If it failed to obtain an access token using the refresh token id, then you will receive 401 again and the client app logic should redirect user to the login page to enter his credentials again and validate to obtain new access token and refresh id.

      • Paoloimg says

        Hi Taiseer,

        I’m in the same situation as Atul and I’m wondering about the simplest approach in order to let the client to request a new token. At this stage I wouldn’t add the complexity required for “refresh token” logic (maybe later if really needed).

        In my specific scenario the client is a mobile app and my need is to avoid asking the user for its credentials each time the token expires, instead I would like to acquire them at the first successful connection attempt, then store them locally on the mobile device and provide them automatically as soon as the token expires… this is aimed to grant a seamless user experience while limiting the user credentials transition which of course are provided through https.
        I would like to know your thoughts about the acceptability of such a solution, and if it’s too out of standard, if it has security criticity which needed to be considered, and so on…

        Thank you very much for your time.

  12. says

    Hello I’m using your example for a project exactly with Web API and AngujarJS. Thank you so much for this serie of posts.

    I have the login and registration working :) , but in my project I need to add a second step for user personal details; so I want to get the UserId from the recently storaged user. ¿How can I access to the user information vía token? I mean if I wanted to get UserId and store it in “session”, I mean in the token, ¿How can I access it after?

    • says

      Anything you add it as a claim in the token before issuing it can be accessed when you decode the token, this can be done as those LOCs
      If you want to get the UserId using “User.Identity.Name” then you should set the UserID as this LOC

  13. Robert says

    I’ve modified bits and pieces of this, but for the most part it stays structurally like what you have above. I’m running into issues on the Web API side though.

    When I do the token part (renamed the route to authorize), I receive back the access_token, token_type, and the expires_in as expected. So far so good. But when I attempt to use in my GET request Headers Content-Type (and Accept) application/json and Authorization of Bearer TOKENGENERATEDINPREVIOUSPOST, I receive 401 unauthorized (message Authorization has been denied for this request.

    I’ve checked and Windows authentication is off and Anonymous is on. I’m thinking that somehow I’m generating the tokens, but they’re not persisting beyond the response of the post? Is there an area to look to check on that?

    • says

      Hi Robert,
      If you checked all possible areas where you might receive 401, the only thing remains that might result in 401 is using an expired access token, make sure you setting the access token life time to a long enough timespan where you can test the API.

  14. Mark says

    What if I want to implement token based security into my existing angular/asp.net application? Where would I start?

    • says

      If your API is owin enabled then you can follow up with the post very easily, this is the only thing you need to take care of, which is making your Api OWN ready

      • Mark says

        I tried adding a nuGet package but it failed, that’s why I am not sure where to start. Here is what I get:

        Install-Package : Could not install package ‘Microsoft.AspNet.WebApi.Client 5.1.2′. You are trying to install this package into a project that targets ‘.NETFramework, Version=v4.0′, but the package does not
        contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.At line:1 char:1
        + Install-Package Microsoft.AspNet.WebApi.Owin -Version 5.1.2
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : NotSpecified: (:) [Install-Package], Exception
        + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand

        Any idea?

  15. Gurpreet Singh says

    Hello Taiseer,
    Trust you are doing well.
    I like what you have shared and it’s been very useful for me in my recent projects :) Thanks again
    I just need little more from you :) How I can add Windows Authentication as well with the same architecture. Any suggestion or solution from will help me lot.
    Thanks again and keep great work going

      • Gurpreet Singh says

        Thanks, Yes I have that working now with Windows Auth settings. I was basically looking for how I can add user for Windows Users in application so that I can do assign them some roles. Thanks again! will update you how it goes.

  16. says

    A top article. Wanted a robust auth solution that could serve many types of clients and this fits the bill well.

    Still largely working well a year on. I had to remove the nuget -v restrictions and get the latest of everything. Some of the dependencies are out date but going a fresh nuget grab of the missing ones it moans about at runtime gets this working perfectly

  17. says

    There isn’t a comprehensive material on the internet that spells out how OAuth work like you do in this article. This article is exactly what I was looking for. Thanks.

  18. Neil says

    With this implementation is it possible to achieve the following scenario.

    I have multiple WebAPI (two at the moment but could be more) and a MVC web application and would like to implementation authentication and authorisation across all three, is it possible to implement the /token OWIN solution in a separate web application to issue the Bearer token and validate that in the different web applications?

  19. says

    HI Taiseer, first at all thank you very much for the tutorial. I am using angularjs v1.3.15 and trying to use a web api that I put together with your instructions. My problem is that I get the token but when I trying to execute a GET I get “GET http://localhost:26264/api/orders 401 (Unauthorized)”. I was able to register the account as well thats why I got the token.

    My angularjs service is
    ‘use strict';
    app.factory(‘categoriesService’, [‘$http’, ‘ngAuthSettings’, function ($http, ngAuthSettings) {

    var serviceBase = ngAuthSettings.apiServiceBaseUri;

    var categoriesServiceFactory = {};
    var _getCategories = function () {

    return $http.get(serviceBase + ‘api/orders’).then(function (results) {
    return results;
    });
    };

    categoriesServiceFactory.getCategories = _getCategories;

    return categoriesServiceFactory;

    }]);

    If you can help me, I really appreciate it
    Hank

  20. stalemate090 says

    Just a heads up to anyone that may have been copy/pasting grant_type=password&username=”Taiseer”&password=”SuperPass” into a REST client to get a token

    – Remember to get rid of the quotation marks around “Taiseer” and “SuperPass”

  21. Kusi Appiah says

    Dear Taiseer,

    Thanks for your spot on tutorials.

    I will be grateful if you can implement it in my angularjs application.

    Best Regards,

    Kusi

      • Kusi Appiah says

        Hi Taiseer,

        I didn’t mean to say you to implement it in my app, but rather how to implement it in my app. Sorry for that.

        However, I have gone through your last tutorials which covered backend, but I having challenges in implementing roles to show only authorized pages per user role.

        I will be grateful for your direction.

        Best regards.

  22. Kusi Appiah says

    Hi,

    Your step by step approach this tutorial has really helped me, after weeks of research and cracking my brains to add authentication to my angularjs application.

    However, how do I add role-based authorization to my application.

    I will be grateful for your assistance.

    Best regards.

    • says

      Glad it was useful, check my last tutorials where I cover the backend part. There is a lot of Posts covering roles authorization with Angularjs, most of them with NodeJS back end, but you can get the idea.

  23. Milan says

    I am getting {“error”:”invalid_grant”,”error_description”:”The user name or password is incorrect.”}
    what suppose to be table structure on DB?

  24. Milan says

    and also is there any way that I can use my own db with custom user table? i dont want to use default user table created by asp.net.

  25. says

    Hello,

    First of all, a thanks for your posts. It is really helpful.

    Here is my application set up.
    Application 1: Traditional ASP.NET MVC application
    Application 2: Hybrid Mobile App (ionic + Angularjs) along with ASP.NET Web API as backend service layer.

    I want to host, both ASP.NET MVC application(app1) and ASP.NET Web API(app 2) together on same domain.

    Your post will very well fit for my Application 2 setup.
    So my confusion is
    1) Is it good practice to host both together and have common authenticatyion code in place?
    2) If Yes, how can I use same authentication setup for that as well? When user login from my web application, do I need to redirect login request to web api authentication code? I am really not sure how to connect both.

    thanks

  26. says

    Joudeh,

    You posts have been really useful to me in my projects.

    I am using ASP.NET Web Api 2.0 to implement an Android (iOS) app that would consume the REST Api. The basic authentication method works, but it adds a step to whole process, when you want to verify the username (in my case it would be email). So I wanted to implement the authentication & authorization using Google Accounts on mobile (client).

    Could you please add a section that explains the steps achieving that? I have been looking all over the Internet & couldn’t find any.

    Thanks,
    Kunal Bajpai

      • says

        Following your tutorial I am able to achieve almost 99%. The rest 1% is this, I am trying to authorize a mobile user to consume the Web API 2. The authentication flow works flawlessly; the problem is regarding the UX. When the user wants to access my API they are redirected to a Google API authorization page where User selects level of authorization they want to give to API. The confirmation page is being loaded in a WebView fragment & the user has again fill-in their credentials. This is almost against why I want to implement OAuth. Is there a way to load the pre-authorized account so that the user doesn’t have to fill in the account username & password again?

  27. Anyj says

    Hi Taiser

    I learned something from your post.But the ASP.NET Identity and EF make me confused cause I know little about it. I want my own database schema,and I have no idea how to apply my own database(with users information) to your demo project.Need your help,thanks a lot!

  28. zhixing says

    Dear Instructor,
    After step 7, I try to use postman to register a user. However, I got an error:

    {
    “message”: “The request entity’s media type ‘multipart/form-data’ is not supported for this resource.”,
    “exceptionMessage”: “No MediaTypeFormatter is available to read an object of type ‘UserModel’ from content with media type ‘multipart/form-data’.”,
    “exceptionType”: “System.Net.Http.UnsupportedMediaTypeException”,
    “stackTrace”: ” at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\\\r\\\n at System.Net.Http.HttpContentExtensions.ReadAsAsync(HttpContent content, Type type, IEnumerable1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\\\r\\\n at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)”
    }

    Could you please teach me how to fix this problem.
    Thank you so much!

  29. Conor McCarthy says

    Hello Taiseer,

    I am trying to maintain an application and move it to Azure. The application has a Web API which has implemented a sort of hybrid of Cookies and Token based Owin authentication. When the Token API call is made, it sets a cookie which contains the access token. Subsequent API calls which are marked with the “Authorize” attribute rely on this authentication cookie being sent by the browser.
    Outside of Azure, when the Web API is being called from an Angular website on the same host, this works fine. However, when the Web API and the Web App are put in 2 separate Azure apps (an API app and a Web App) – the browser stops sending the Cookie on requests after the Token method is called successfully.
    I have tried to follow advice in this article
    http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
    about enabling Cors and specifically allowing credentials to be passed.

    I am trying to reconcile this with the information in your excellent article – and this is where I am confused.

    I have 2 questions –
    1. Everything in the article above relates to the package Microsoft.Aspnet.WebApi.Cors and applying the EnableCors attribute on Web API. Your article implies that I don’t need to be concerned with this if I am using OWIN, as your Step 11 above says that it is all that is needed to apply Cors policy to the Web API. Is this correct?
    2. When I tried to make the client code send credentials ($httpProvider.defaults.withCredentials = true), the result is an error:
    Credentials flag is ‘true’, but the ‘Access-Control-Allow-Credentials’ header is ”. It must be ‘true’ to allow credentials.
    I thought that the corsOptions.AllowAll option would also set the Access-Control-Allow-Credentials header in all cases, but it does not seem to.

    I hope this is clear – and thanks for this article and your others which have helped my understanding.

    • says

      Hi Conor,
      As long you are using cookies to establish authentication, then the cookie will not be transmitted from host X to host Y, enabling CORS will allow you to send requests from JS to another domain. Please read this post

  30. Tony says

    Hi TAISEER,

    I would like to say thank you for sharing the very helpful article. I try to follow your instruction, everything works well but I have a requirement is that the authenticating belongs to another service. I mean the following snippet.

    using (AuthRepository _repo = new AuthRepository())
    {
    IdentityUser user = await _repo.FindUser(context.UserName, context.Password);

    if (user == null)
    {
    context.SetError(“invalid_grant”, “The user name or password is incorrect.”);
    return;
    }
    }

    I must use Unity to config for loading another service in order for using it in SimpleAuthorizationServerProvider class. Do you have any suggestion? Thanks again for your good work. You have made developers like me feel comfortable in learning new technologies :)

  31. says

    Hello great article!
    It helps me a lot to secure 2 Web API I am currently working on.
    Just a question on one of my API I already check credentials against an internal LDAP server.
    How can I replace EF database of user/password with my LDAP system ?

  32. Mazin says

    Do i have to have SQL server installed in the computer to connect to the database? i thought visual studio 2013 comes with a embedded SQL server or something….. when i try to carry out step 7 i get a status of 500, this is the inner exception:
    “A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 – Error Locating Server/Instance Specified)”

  33. says

    Hi Taiseer

    Thank you very much for this post. I need to implement exactly this functionality in my thesis project. Unfortunately I have some problems to implement this into my solution.

    First, the basic part is working correctly. I have a Mobile Client on which i can register a new User. Then i can Login and receive the token. When i then make a request the token is sent in the Request Header. It all works fine.
    My problem is, that I get an 401 Unauthorized error if I call a [Authorize] Method, even if i send the token. So i removed the [Authorize] Annotation to test some things:

    var z = User.Identity;
    var t = Thread.CurrentPrincipal.Identity;
    var y = HttpContext.Current.User.Identity;
    var x = Request.GetOwinContext().Authentication.User.Identity;
    Here i got alwas the same Identity: AuthenticationType=null; IsAuthenticated=false; Name=null; Claims:empty

    var token = Request.Headers.Authorization;
    Here i get the right token. So the token is sent by the request.

    I home you can help me. I have the token but no identity.

  34. Ralph says

    Hi Taiseer!

    Thanks for sharing your knowledge!

    I followed your tutorial and where we request the token on /token, is there any way to implement any logic before handling out it?
    I mean, the user will log in into the web api, then I will have a internall process of approving that user and sending back the token.

    I don’t know where to put this logic since it goes to /token and I don’t have this controller…

    Could you help me please, direct me into where I could try it?

    Thanks.

    Ralph

  35. Jeffery says

    First off, thanks for the excellent tutorial. I have a question on dealing with services. I’m building an api, that in turns connects to another external api. not for authentication such as the case with facebook and google. but to sync data between the two applications More specifically I’m connecting to the quickbooks online api. using their provided .net sdk. They provide a sample implementation that uses aspnet mvc 5 and the models use the DTO/ repository pattern.

    Your implementations use POCO.

    According to the link http://www.asp.net/web-api/overview/data/using-web-api-with-entity-framework/part-5
    DTO’s “Decouple your service layer from your database layer.”

    The Intuit Sample app code referenced is located here
    https://github.com/IntuitDeveloper/SampleApp-TimeTracking_Invoicing-DotNet

    Any suggestions on how I should go about this.
    I really appreciate any feedback that you can provide on this

  36. says

    Hi Taiseer,

    thank you for this great post! But i have a connection on the database:

    You wrote that i have a Class “UserModel” and a ConnectionString in the web.config. But you have no DB create script provided for this db!? Or am i wrong? Or can i create a database with this three fields only?

  37. says

    I’m a little confused by the separation of responsibilities you implemented. You have created two different servers to comply with the different roles of OAuth v2 (Authentication and Resources servers). Yet you put the “OrdersController” on the Authentication server when I expected it to be on the Resources server. Was this an oversight or do I not understand OAuth?

    My expectation was that you would get the token from the Authentication server and use that in requests for user data from the Resources server.

  38. Devon says

    To be clear the Post works OK and a token is returned. It’s when sending the get request with the bearer token returned from the POST request that the error occurs:

    GET /token?Accept=application/json&Content-Type=application/x-www-form-urlencoded&Authorization=Bearer mc0UaZiHM97ueb8xiEQqeZ5oCwMnF6ZoKgEHp0cd8ftSQ5MCAHkwo6HAcOPFQil3k7hjD-dB-tX5OHTzlmbP8ncHUU6ZMt8a1OYVGhv59AzN1f7YiaNydHPnIrjbI-U74aEtAyFrmghtK0_JjIvBBGM3kxYW1hVFP_BDhljFA33LVhEfzqQFxGJIobIv0C6gHfoqeXjW9g857BUSA1xjk24PmaQK9KFORugmK6Jx68s HTTP/1.1
    Host: localhost:35075
    Content-Type: application/json
    Cache-Control: no-cache
    Content-Type: application/x-www-form-urlencoded

  39. says

    Hi Devon, you do not need to send Get request to /token endpoint again, you need to send it to the secured endpoint which is “/orders” and set the token. As well the content type should be application/json when sending this request. Hope this answers your question.

  40. Devon says

    Finally noticed I forgot to change my url on the get. Silly mistake. Also had accidentally left the URL params tab click in postman rather than Headers. Trying to work too quickly as the end of the day neared.

  41. Hemant says

    You Saved My Life man…….Worked Like Charm………On My Production ……….Building something for NGO will surely put link to your blog …..

    Thanks Taiseer…..Really Nice Blog

  42. Tom says

    Hi Taiseer,
    I’m getting “unsupported_grant_type”, but what do you mean with “Build the request like this https://www.getpostman.com/collections/1ff438e088efac658be8

    I have this request:

    POST http://localhost:53701/token HTTP/1.1
    User-Agent: Fiddler
    Host: localhost:53701
    Content-Length: 248
    Accept: application/json
    Content-Type: application/x-www-form-urlencoded

    [
    {
    “key”: “username”,
    “value”: “Test”,
    “type”: “text”
    },
    {
    “key”: “password”,
    “value”: “MyPass”,
    “type”: “text”
    },
    {
    “key”: “grant_type”,
    “value”: “password”,
    “type”: “text”
    }
    ]

  43. Jiten says

    Hey Taiseer ! Need your help.

    I need to invoke /Token endpoint from OAuth service itself and generate access token and refresh token explicit once your change his password and pass tokens to client. I don’t want user to login again.

    Thanks,
    Jiten

  44. Aibol says

    Dear Taiseer,

    I faced the following problem:

    XMLHttpRequest cannot load http://localhost:57606/token. No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:32153′ is therefore not allowed access.

    The problem occurs in Chrome browser. In IE it’s ok. Don’t you know what the problem could be?

  45. says

    Hi Aibol,
    I believe you need to set the client allowed origin column to match your host i.e. “http://localhost:57606″, CORS is not configured correctly in your case. Check this post on how to do it.
    IE doesn’t consider the port in URI as different URI that’s why it is working correctly because it only checks the host-name “localhost”, Chrome, Firefox take care of the port as well.

  46. says

    Hi Jiten,
    With the current implementation you can’t do this, what you can do is to use refresh tokens and once the user change his password you delete his refresh token. So when the client application wants to use this refresh token to obtain new access token it will receive 401 and you need to re-authenticate him by providing username and his new password.

  47. Aibol says

    Thank you Taiseer. Yes, you’re correct! The problem was in not configured CORS, e.g. there weren’t any rows in Client table.

    Unfortunately, I faced another problem when FindClient method is invoked:

    An exception of type ‘System.Data.Entity.Core.ProviderIncompatibleException’ occurred in EntityFramework.dll but was not handled in user code

    Additional information: An error occurred accessing the database. This usually means that the connection to the database failed. Check that the connection string is correct and that the appropriate DbContext constructor is being used to specify it or find it in the application’s config file. See http://go.microsoft.com/fwlink/?LinkId=386386 for information on DbContext and connections. See the inner exception for details of the failure.

    Could you also to clarify what is the difference between the RefreshTokenLifeTime which is saved in Client table and AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(30) in Startup.cs?

  48. says

    Hi Aibol, I’ve covered the difference in the post, but the AccessTokenExpireTimeSpan is used to determine the life time for the local access token, the RefreshTokenLifeTime is used to determine the validity for refresh toke, usually this value is big (1 month, 2 weeks). Once this value expires user needs to re-authenticate again be providing credentials.

  49. Jerry T says

    I ran into this problem as well and used PostMan (a Chrome app) to send the JSON string to the url as a Post request and now it works. Caused me a bit of frustration till I realized this. Maybe you can add it to the blog post where you tell people to test the url so it’s right next to the proper step? :-)

    And thanks for all the work done with these blog posts. I really need this info and it looks like this will be perfect for a new project I have to start.

  50. says

    That is strange, it should be working correctly.
    This is how my request look like:

    POST /token HTTP/1.1
    Host: ngauthenticationapi.azurewebsites.net
    Accept: application/json
    Content-Type: application/x-www-form-urlencoded
    Cache-Control: no-cache
    Postman-Token: 3fc06f29-8f4f-54ed-10c2-3f3045dc8dfa

    username=Taiseer&password=SuperPass&grant_type=password

  51. Tom says

    Hi all,
    I have solved my problem whit “unsupported_grant_type” using this request:

    POST http://localhost:53701/token HTTP/1.1
    User-Agent: Fiddler
    Accept: application/json
    Content-Type: application/x-www-form-urlencoded
    Host: localhost:53701
    Content-Length: 51

    grant_type=password&username=myuser&password=mypsw

Trackbacks

Leave a Reply