ASP.NET Identity 2.9 Cookie & Token

ASP.NET Identity 2.0 Cookie & Token Authentication

knowventBanner

This tutorial is centered around building an application that will support multiple platforms. The need to support a web application along with a complement of mobile apps is not uncommon. This tutorial will focus on setting up ASP.NET Identity 2.0 in a ASP.NET MVC application with WebAPI Support.

Update: If you are interested in two factor authentication then check out my new article on ASP.NET Identity 2.0 Two Factor Authentication

Use Case

The need for an authentication solution what will support both web and a native mobile application is a real need. One user store multiple authentication methods. We will need the web application to authentication using cookies and the mobile counterpart will need to use a token-based authentication.

What We Are Using?

  • Visual Studio 2013 – MVC/Individual Authentication project Template
  • ASP.NET Identity 2.0 (Pre-release)
  • ASP.NET MVC 5 & WebAPI
  • OWIN Identity Middleware

Install Prerequisites

I am using a ASP.NET MVC template with Individual Authenication found in the Visual Studio 2013 project setup. At the time this article was written, ASP.NET Identity 2.0 was still in pre-release. To demo the ASP.NET Identity 2.0 I updated my Nuget Identity packages to the pre-release versions. I have listed below the details of the packages used (some are defaults of the Visual Studio project initialization).

Id                             Version              Description/Release Notes                                                                                                                 
--                             -------              -------------------------                                                                                                                 
Antlr                          3.4.1.9004           ANother Tool for Language Recognition, is a language tool that provides a framework for constructing recognizers, interpreters, compile...
bootstrap                      3.0.0                Sleek, intuitive, and powerful front-end framework for faster and easier web development.                                                 
EntityFramework                6.1.0-beta1          Entity Framework is Microsoft's recommended data access technology for new applications.                                                  
jQuery                         1.10.2               jQuery is a new kind of JavaScript Library....                                                                                            
jQuery.Validation              1.11.1               This jQuery plugin makes simple clientside form validation trivial, while offering lots of option for customization. That makes a good ...
Microsoft.AspNet.Identity.Core 2.0.0-beta1          Core interfaces for ASP.NET Identity.                                                                                                     
Microsoft.AspNet.Identity.E... 2.0.0-beta1          ASP.NET Identity providers that use Entity Framework.                                                                                     
Microsoft.AspNet.Identity.Owin 2.0.0-beta1          Owin implementation for ASP.NET Identity.                                                                                                 
Microsoft.AspNet.Mvc           5.0.0                This package contains the runtime assemblies for ASP.NET MVC. ASP.NET MVC gives you a powerful, patterns-based way to build dynamic web...
Microsoft.AspNet.Razor         3.0.0                This package contains the runtime assemblies for ASP.NET Web Pages. ASP.NET Web Pages and the new Razor syntax provide a fast, terse, c...
Microsoft.AspNet.Web.Optimi... 1.1.1                ASP.NET Optimization introduces a way to bundle and optimize CSS and JavaScript files.                                                    
Microsoft.AspNet.WebApi        5.0.0                This package contains everything you need to host ASP.NET Web API on IIS. ASP.NET Web API is a framework that makes it easy to build HT...
Microsoft.AspNet.WebApi.Client 5.0.0                This package adds support for formatting and content negotiation to System.Net.Http. It includes support for JSON, XML, and form URL en...
Microsoft.AspNet.WebApi.Core   5.0.0                This package contains the core runtime assemblies for ASP.NET Web API. This package is used by hosts of the ASP.NET Web API runtime. To...
Microsoft.AspNet.WebApi.Web... 5.0.0                This package contains everything you need to host ASP.NET Web API on IIS. ASP.NET Web API is a framework that makes it easy to build HT...
Microsoft.AspNet.WebPages      3.0.0                This package contains core runtime assemblies shared between ASP.NET MVC and ASP.NET Web Pages.                                           
Microsoft.jQuery.Unobtrusiv... 3.0.0                jQuery plugin that unobtrusively sets up jQuery.Validation.                                                                               
Microsoft.Owin                 2.0.2                Provides a set of helper types and abstractions for simplifying the creation of OWIN components.                                          
Microsoft.Owin.Host.SystemWeb  2.0.0                OWIN server that enables OWIN-based applications to run on IIS using the ASP.NET request pipeline.                                        
Microsoft.Owin.Security        2.0.2                Common types which are shared by the various authentication middleware components.                                                        
Microsoft.Owin.Security.Coo... 2.0.2                Middleware that enables an application to use cookie based authentication, similar to ASP.NET's forms authentication.                     
Microsoft.Owin.Security.Fac... 2.0.0                Middleware that enables an application to support Facebook's OAuth 2.0 authentication workflow.                                           
Microsoft.Owin.Security.Google 2.0.0                Middleware that enables an application to support Google's OpenId authentication workflow.                                                
Microsoft.Owin.Security.Mic... 2.0.0                Middleware that enables an application to support the Microsoft Account authentication workflow.                                          
Microsoft.Owin.Security.OAuth  2.0.2                Middleware that enables an application to support any standard OAuth 2.0 authentication workflow.                                         
Microsoft.Owin.Security.Twi... 2.0.0                Middleware that enables an application to support Twitter's OAuth 2.0 authentication workflow.                                            
Microsoft.Web.Infrastructure   1.0.0.0              This package contains the Microsoft.Web.Infrastructure assembly that lets you dynamically register HTTP modules at run time.              
Modernizr                      2.6.2                Modernizr adds classes to the <html> element which allow you to target specific browser functionality in your stylesheet. You don't act...
Newtonsoft.Json                5.0.6                Json.NET is a popular high-performance JSON framework for .NET                                                                            
Owin                           1.0                  OWIN IAppBuilder startup interface                                                                                                        
Respond                        1.2.0                The goal of this script is to provide a fast and lightweight (3kb minified / 1kb gzipped) script to enable responsive web designs in br...
WebGrease                      1.5.2                Web Grease is a suite of tools for optimizing javascript, css files and images. 

Some New Patterns with ASP.NET Identity 2.0

If you are not familiar with OWIN this is a effort by Microsoft to create more modular, decoupled software with quicker release cycles. MVC 5 and ASP.NET Identity uses many different OWIN middle components. If you would like to get more information about OWN you can read more about it here.

The ASP.NET Identity includes support for creating a single instance of a the UserManager and the identity DBContext per application request. To support this pattern use the follow extension methods per the IAppBuilder object:

app.CreatePerOwinContext<AppUserIdentityDbContext>(AppUserIdentityDbContext.Create);
app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);

Here is the AppManager Class:

public class AppUserManager : UserManager<AppUserIdentity>
{
    public AppUserManager(IUserStore<AppUserIdentity> store)
        : base(store) { }

    public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
    {
        var manager = new AppUserManager(new UserStore<AppUserIdentity>(context.Get<AppUserIdentityDbContext>()));
        return manager;
    }

}

To get the AppManager object during a MVC Controller execution:

private AppUserManager _userManager;
public AppUserManager UserManager
{
    get
    {
        return _userManager ?? HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
    }
    private set
    {
        _userManager = value;
    }
} 

How to Setup ASP.NET Identity 2.0 to Support Cookie and Bearer Token Authentication

Like I mention above, there is a real world need to have an application support both web-based and native mobile applications. This requires two authentication modes: Cookie Authentication for your web-based application and the token authentication for mobile/rich client scenarios.

Since the Visual Studio 2013 project setup supports Cookie authentication out of the box. So, this article will focus primarily on how to dovetail WebAPI and Token Authentication to use the same User Store.

Setup WebAPIConfig

The first task is setting up the Startup class:

    public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; }

    public void ConfigureAuth(IAppBuilder app)
    {
        app.CreatePerOwinContext<AppUserIdentityDbContext>(AppUserIdentityDbContext.Create);
        app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);

        OAuthBearerOptions = new OAuthBearerAuthenticationOptions();
        app.UseOAuthBearerAuthentication(OAuthBearerOptions);

        //...Cookie Auth Setup here...//
    }

Here we are setup the context singleton for the DBContext and UserManager (as mention above). The important part of this snippet for authentication is initializing the bearer options object and adding the UseOAuthBearerAuthentication middle ware authentication to the pipeline. This will enable the app to use Bearer Tokens for authentication.


The next task required to support WebAPI auth is to suppress cookie authentication on API requests. This is done by added in the following code to the WebApiConfig Register method.

public static void Register(HttpConfiguration config)
{
    //...Route Registration...///

    config.SuppressDefaultHostAuthentication();
    config.Filters.Add(new HostAuthenticationFilter("Bearer"));
}

The first method tells the pipeline authentication to fall through to the request handler. The second adds an authentication handler that will validate the authentication HTTP host headers. This configuration tells the handler to look at the Authorization Header value of “Bearer abcedefghijklmnopqrstuvwxyz1234567890” as the token. More on this later.

Do Note the two methods used are extension methods found in a OWIN package. If these methods can’t be resolved you will probably need to install the following package:

`Install-Package Microsoft.AspNet.WebApi.Owin`  

Get Your Token

The HostAuthenticationFilter will look for an authorization header for all [Authorize] annotated controllers/method. This requires an authentication process that returns a bearer token. The Microsoft.Owin.Security will come in to play here. The code below shows how to create a ticket based on the user’s claims Identity and generated a token based on the security ticket. It returns a token that will expire in 30 minutes.

public String Authenticate(string user, string password)
{

    if (string.IsNullOrEmpty(user) || string.IsNullOrEmpty(password))
        return "failed";
    var userIdentity = UserManager.FindAsync(user, password).Result;
    if (userIdentity != null)
    {
        var identity = new ClaimsIdentity(Startup.OAuthBearerOptions.AuthenticationType);
        identity.AddClaim(new Claim(ClaimTypes.Name, user));
        identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userIdentity.Id));
        AuthenticationTicket ticket = new AuthenticationTicket(identity, new AuthenticationProperties());
        var currentUtc = new SystemClock().UtcNow;
        ticket.Properties.IssuedUtc = currentUtc;
        ticket.Properties.ExpiresUtc = currentUtc.Add(TimeSpan.FromMinutes(30));
        string AccessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);
        return AccessToken;
    }
    return "failed";
}

When successfully authenticated you will get a token like hBJi26lVQwUJF6f7roDy-oVnV_VeX20m52xL2dzF1q5IQPkt3n30610UbpFl9JV75........ Passing this in with each request’s authorization header is all that is needed to authenticate the request. Be sure to include the ‘Bearer’ designation along with the token like Bearer hBJi26lVQwUJF6f7roDy-oVnV_VeX20m52xL2dzF1q5IQPkt3n30610UbpFl9JV75.......


You will now be able execute the following method that will return the userId and User name.

[Authorize]
[HttpGet]
[ActionName("ValidateToken")]
public String ValidateToken()
{
    var user = this.User.Identity;
    if (user != null)
        return string.Format("{0} - {1}", user.GetUserId(), user.GetUserName());
    else
        return "Unable to resolve user id";

}

Feel free to download the GitHub source code (or Zip) that goes along with this article.

Let us know if this help you.

Posted in .NET, API, MVC, Security, Uncategorized.
  • khurram

    IdentityFactoryOptions is giveing me error

    • Justin Hyland

      I imagine you are getting an invalid reference to the IdentityFactoryOptions object. The is part of the Owin identity package. Make sure your project has the Microsoft.AspNet.Identity.Owin Nuget package installed (prerelease 2.0 beta-1). You should see a project reference to Microsoft.AspNet.Identity.Owin library.

  • arecoba

    Thank you, but I want to use this solution using MongoDB.AspNet.Identity. Can you help me ?
    I have probleme to convert Entity Framework class.

    Thanks in advance

  • Valentino Rijhen

    Nice project, but I cannot run it. Does it have to do with a missing MasterKey database? Do you already have an example? Where can I find this? Thanks in advance.

    • Justin Hyland

      I guess if you had a specific error I could speak to your issue. The
      Identity database will be automatically created on the localDB SQL
      instance when application first runs.

  • mikeysee

    Hi Justin,

    Good article. Im confused however. What happens if you are running a native mobile app with the Facebook SDK for example. FB will just return you an access token, how do you then use that to authenticate the user using WebAPI?

    Cheers,
    Mike

    • Justin Hyland

      Mike,

      Thanks for reading. This article maintains that you will use ASP.NET identity 2.0 User provider (its own user name and passwords). Facebook’s authentication tokens don’t really do much good with anything but Facebook and their services.

      It is difficult to tell what your authentication workflow needs to be. If want to share FB authentication you will need to “Test” the access token on your server for each request made to the WebAPI. This falls outside of the ASP.NET Identity 2.0 discussion since you don’t need a identity provider or a token service (your using Facebooks)

      You can find a good example in one of my projects where I validated WebAPI requests based on a token passed in: https://github.com/hylander0/WebApiSoup

      Basically, you will need to setup a custom Auth MessageHandler where you will get the access token and Facebook user id and test it (good examples here: http://stackoverflow.com/questions/5406859/facebook-access-token-server-side-validation-for-iphone-app). If Facebook says it is a valid token then they are good to go and let them use the WebAPI. If not then reject the request.

      I hope that helps.

    • mikeysee

      Thanks for your reply Justin.

      I think the way I need to do it based on what this guys is talking about: https://thewayofcode.wordpress.com/2014/03/01/asp-net-webapi-identity-system-how-to-login-with-facebook-access-token/#comments

      Unfortunately I think his example is using an older version of WebAPI, I guess ill just have to try hacking around until I can get it to work.

      Its strange that Microsoft dont include an example for this which seems like a very common use scenario.

      Mike

  • Richard

    Hi Justin,

    I implemented Identity the way you described it. I just can’t find out how to request a token from my webinterface. I have a WPF application and the old way I used client.PostAsync. What should I use now?

    Thx,
    Richard

  • Richard

    Hi Justing,

    I created my webapp with identity the way you describe it. In the past I worked with the provider and used client.PostAsync to login from my WPF app to my webapp. How does it work with the code you described above?

    Thx,
    Richard

    • Justin Hyland

      Richard,

      I did notice something with the sample project since you
      brought this up. The Authenticate action
      in the API controller was accepting a GET rather than a POST (since GET expose
      you to Cross-site scripting attack). I
      have changed this and pushed up the changes.

      Regardless, I will go through the step to implement your solution. Using the Sample application that goes along
      with this article your process will look something like this:

      1) WPF app Collects the User name and password

      2) The WPF app will executes a client.POSTAsync (HTTP POST) to url http://localhost/api/Account/Authenticate?user=Admin&password=123456

      3) Grab the TOKEN. The response body will contain the token
      used for further, authenticated requests in the WPF app

      4) All subsequent requests should pass the token like “Bearer
      {TOKEN}” via the HTTP authorization header. Here is
      an example of adding a header to a client request: http://stackoverflow.com/questions/12022965/adding-http-headers-to-httpclient-asp-net-web-api

      Let me know if that helps.

      ~~

      Justin

  • khasi asmarani

    I not see a kind of authorization in your example.

  • Ricky

    Hi,
    Great article. I downloaded the source code, The remember me (cookie authentication) works fine in localhost, however, when I deploy to a web server, it doesn’t seems to work. Can you point me to right direction? Thanks

  • Alberto Ruiz

    Would you be kind and post an example request made from fiddler, I have been trying to test the Authenticate method but always get a 404 not found. Great article!

  • Raj

    Hi

    referring to this line

    var user = this.User.Identity;

    I have a business layer in my app where I want to move all this logic to about getting User details etc. Is this possible?

    • Justin Hyland

      Sorry for the delay. As long as the business layer is running under the same app domain context as the asp.net application you can gain access to the user name and claims. ASP.NET identity uses the CurrentPrincipal.Identity object (http://msdn.microsoft.com/en-us/library/system.threading.thread.currentprincipal(v=vs.110).aspx). You will not have access to the identity manager object unless you pass the object to the business layer or implement Dependency injection.

  • Justin Hyland

    Lyle, Make sure you are passing the token back to the server when you are calling the validate or any other secured API call. The token must be supplied in the header name “Authorization” and the value of the header should be formatted like “Bearer abcedefghijklmnopqrstuvwxyz1234567890”.
    Your token value must start with word “Bearer” and include your take afterwords.

    Also, make sure you are executing the correct http method on each API request. The ValidateToken requires the request to be an HTTPGET

  • Naunihal Sidhu

    How do you Invalidate the Token at Server(kind of SignOut) ?
    Also how do you extend the timeout on the Ticket ?

    • Justin Hyland

      Naunihal Sidhu Sorry for the delay getting back to you.

      By default, the tokens have their expiration date build in when they are created. The only way to invalidate Tokens is to change the user’s security stamp via UserManager.UpdateSecurityStampAsync(userId); This will cause all cookie based sessions and/or issued tokens to no longer be valid. Basically, just makes it so the user has to sign in to everything again.

      There is no way to “signout” a token individually you have to wait for them to expire (this is why some say bearer tokens are a bad idea).

      I hope that helps.

  • Justin Hyland

    Kiriz refering to the MasterKeyAuthentication Project. The very first thing you need to do is get a token. Call the method String Authenticate(string user, string password) by executing a GET against URL http://{YOUR_SERVER}/API/Account/Authenticate?user={USERNAME}&password={PASSWORD}

    This will return a string in the response body. That will be your token.

    The ValidateToken is just a test method I created in the project as an example authorized call. To call ValidateToken execute a GET with the HTTP Header –> Key: “authorization” Value: “Bearer {BEARER_TOKEN_RECEIVED}” against URL http://{YOUR_SERVER}/API/Account/ValidateToken. ASP.NET will look at the authorization header value. If is it a valid token (and the call is constructed correctly) you will get your login user info returned in there response body.

  • Daskul

    is there a way to automatically retrieve and pass the token on each request if its not present? most of the examples I’ve seen, they are passing the token manually on each request. What I want is, if I have two projects. ASP MVC 5 WebAPI and ASP MVC 5 webclient. The user will login to the webclient, then everytime the webclient request to the webapi, it automatically pass the token to the webapi or else the webclient will redirect the user to the login page to request credentials to be used to retrieve the token.

    • Justin Hyland

      @daskul:disqus I assume the webclient you describe is a browser client. That is a good question and a valid use case. You will need to register Cookie Auth for browser based auth. This is done in the StartUp class via IAppBuilder like:

      app.UseCookieAuthentication(new CookieAuthenticationOptions
      {
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
      LoginPath = new PathString(“/Account/SignIn”)
      });

      Including both UseOAuthBearerAuthentication & UseCookieAuthentication configurations will allow your WebApi methods to be authenticated against both methods.

      Do that address your question?

    • Daskul

      I will try this one and give you feedback with the results. Thank you!

    • kalyan kankala

      Daskul, where you able to achieve this? I’m working on similar scenario with web api as authentication service and I want to use web api to make sure the user is authenticated before making any calls to mvc (use authenticated token). But how mvc will know the token and have it pass around until user is logged in.

    • Daskul

      I haven’t tried it yet. I am working on different project

    • Justin Hyland

      Approved

  • kalyan kankala

    can you post link to github plz? thanks!