Owin Authentication series
ASP.NET Identity is the reworked, flexible replacement for the old membership system that has been around since ASP.NET 2.0. ASP.NET Identity is more well designed and flexible than the old membership system and uses Owin middleware components for external logins such as Facebook, Google and Twitter.
Compared to the membership system, the architecture of ASP.NET Identity is very much improved and decoupled. Actually, ASP.NET identity doesn’t know (nearly) anything about Owin at all. ASP.NET Identity is working on an application ignorant level, taking care of user and role storage. Then there are the Owin authentication modules that takes care of the actual interaction with the external providers and keeping the user session. The plumping code required is built into the AccountController
created by the new project wizard for ASP.NET projects.
Typical Layering
For a typical application there will be a number of different application layers cooperating to provide the authentication functionality.
- The ASP.NET Identity module sits at the very bottom of the chain, far, far away from the incoming HTTP Request. In fact, it knows nothing about Http at all.
- The MVC AccountController provides all the plumbing to make the different modules interact with each other.
- The Google Authentication Middleware interacts with Google to provide Google signon. In this example I only show Google, but if more social networks such as Facebook or Twitter were offered, they would be next to the Google middleware in the stack.
- The MVC Acount Controller is the generated MVC controller that ties all of the layers together.
- The ASP.NET Identity module handles user and secure password storage, role mapping etc.
ASP.NET Identity
The ASP.NET Identity module is way more flexible than the old membership system. There is the core functionality with handling user sign in etc. and then there is an extensible storage system where you can plug in your own storage. By default MVC projects generate a setup with an Entity Framework based storage provider, but you can plug in anything else instead. I won’t go into more details about it as K. Scott Allen has written a great series of post on Core Identity, Customization Options, ASP.NET Identity with the Entity Framework and Implementing ASP.NET Identity that explains all of it.
Owin Middleware
The Owin Middleware modules are responsible for handling the authentication with external authentication providers (such as Google) and establishing an application session through a cookie. On all subsequent calls the application cookie middleware extracts the contents of the incoming application cookie and sets the claims identity of the current context. For some introduction to Owin middleware, please see What’s this Owin Stuff About?.
The MVC Controller and Local Accounts
The last, but not least part of the stack is the MVC Controller. It is generated automatically in a new application so I guess most people never look at it, but let’s take some time to investigate what it does. For this post, I’ll focus on how local accounts are handled through the Register
and Login
methods.
The post target for the register page is quite straight forward.
// // POST: /Account/Login [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Login(LoginViewModel model, string returnUrl) { if (ModelState.IsValid) { var user = await UserManager.FindAsync(model.Email, model.Password); if (user != null) { await SignInAsync(user, model.RememberMe); return RedirectToLocal(returnUrl); } else { ModelState.AddModelError("", "Invalid username or password."); } } // If we got this far, something failed, redisplay form return View(model); } |
The important thing here is the call to the UserManager.FindAsync
method, which will get the user from ASP.NET Identity if the user name and password match the stored credentials (of course only salted hashes are stored of the password). The MVC controller calls the ASP.NET Identity module in a way that ASP.NET Identity has no dependency on the web infrastructure. In fact, ASP.NET Identity can be used for any kind of application, not only for web applications.
Once the controller has got hold of the user object, it calls the SignInAsync
helper method.
private async Task SignInAsync(ApplicationUser user, bool isPersistent) { AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, await user.GenerateUserIdentityAsync(UserManager)); } |
For now we’ll ignore the call to SignOut
, I will come back to that in a later post when describing how to write a custom Owin authentication middleware. Instead, let’s focus on the call to SignIn
At first sight, the call to AuthenticationManager.SignIn
looks like it is performing the sign in, but that’s actually not entirely true. What it does is to associate a AuthenticationResponseGrant
with the current owin context. After the MVC controller has returned, the owin middleware modules get another chance to act on the response (see image in my Owin introduction post). The application cookie authentication middleware will see the AuthenticationResponseGrant
and issue a session application cookie. This is a main principle of the way Katana (Microsoft’s Owin implementation) works. The layers don’t directly interact with each other, instead they inspect and alter the state of the current request. It is effectively a message passing architecture, where there is no hard dependencies between the different middleware modules. They can always be substitued for another middleware that nows how to handle certain “messages” put in the owin context.
With that, we’re now all done with login in with local credentials. The user is authenticated by ASP.NET Identity. The MVC controller has set the an AuthenticationResponseGrant
property on the Owin context and the application cookie middleware has acted on that and issued a cookie that it will use to authenticate any subsequent requests automatically.
Great article. I’ll add this to my Identity resource map I’m creating.
Hi,
Thanks for you this article. I have a question. What is namespace of AuthenticationManager ? System.Net ? I want to use owin on my project but AuthenticationManager throw an error. I don’t use AuthenticationManager.AuthenticationResponseGrant.
Thanks.
IAuthenticationManager is in the Microsoft.Owin.Security nuget package. It is a property of the standard generated AccountController. The getter is defined as
return HttpContext.GetOwinContext().Authentication;
.Thanks for clarificacion of what this OWIN is about :-)
I am already using ASP.NET Identity and trying to find out if there is a way to get notified for security problems in the components I use in my project (nuGet packages) and the lifecycle of these components. Any input on these topics?