Skip to content

A primer on OWIN cookie authentication middleware for the ASP.NET developer

October 24, 2013

There have been many changes to how authentication is performed for web applications in Visual Studio 2013. For one, there’s a new “Change Authentication” wizard to configure the various ways an application can authenticate users. The approach to authentication that’s undergone the most changes in this version is local cookie-based authentication and external login providers based upon OAuth2 and OpenID (social logins). This style of logins is now collectively known as the “Individual User Accounts” and it’s one option in the new authentication wizard. This purpose of this post (and followup posts) is to explain the new authentication plumbing for this option.

Individual

OWIN authentication middleware

With .NET 4.5.1, for ASP.NET applications, all the underlying code that handles “Individual User Accounts” (as well as the templates in Visual Studio 2013) is new. This means for cookie based authentication we no longer use Forms authentication and for external identity providers we no longer use DotNetOpenAuth.

The replacement is a framework called OWIN authentication middleware and it’s targeting the OWIN API. I don’t plan to motivate OWIN here (this a good article on the subject), but in short it’s an abstraction API for the web host. Many frameworks such as Web API and SignalR (as well as other non-Microsoft frameworks) are coded to this abstraction so they do not require any particular web host (such as IIS).

So this OWIN authentication middleware is the new framework for authenticating users. The two main options we have is local authentication where the users enter credentials into the application itself, and external logins where the user is redirected to the various social login providers that are supported by Microsoft.

This post will only cover the cookie approach. Subsequent posts will describe the others.

OWIN cookie authentication middleware

Previously, for local authentication we used to use Forms authentication and its job was to issue a cookie to represent the current logged in user. Upon subsequent requests from the user, Forms authentication would validate the cookie and make a principal object available that represents the user’s identity.

Now, the new cookie-based implementation is called the OWIN cookie authentication middleware. This performs the same task — it can issue a cookie and then validates the cookie on subsequent requests. One improvement the OWIN cookie authentication middleware has over the previous Forms authentication is that it is claims-aware.

Another function of Forms authentication was that when the application issued a 401 unauthorized HTTP status code, Forms authentication would convert the response into a 302 redirect to the application’s login page. Well, the new cookie authentication middleware does that too.

Configuration

The new OWIN cookie authentication middleware is configured in App_Start/Startup.Auth.cs and consists of these lines of code:

public void ConfigureAuth(IAppBuilder app)
{
   app.UseCookieAuthentication(new CookieAuthenticationOptions
   {
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
      LoginPath = new PathString("/Account/Login")
   });
}

This API call is configuring an identifier (or name) for this authentication middleware (AuthenticationType) and this is needed since there can be different authentication middleware. Also, this name influences the name of the cookie that will be used. The LoginPath is simply the URL to the login page when unauthorized requests need to be redirected.

Redirect to login

As mentioned above, the OWIN cookie middleware will redirect unauthorized requests to the login page. This is only performed if the LoginPath is set. If it’s not set, then this feature is disabled.

Login

On the login page once the user’s credentials have been validated, we can call into OWIN to authenticate the user. We don’t call the cookie middleware directly, instead we call into the “OWIN Authentication Manager”, which is an abstraction for all of the possible OWIN authentication middleware that’s being used. This call can be seen in the new templates and here’s the code if you wanted to invoke it yourself:

var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, "Brock"));
claims.Add(new Claim(ClaimTypes.Email, "brockallen@gmail.com"));
var id = new ClaimsIdentity(claims,
                            DefaultAuthenticationTypes.ApplicationCookie);

var ctx = Request.GetOwinContext();
var authenticationManager = ctx.Authentication;
authenticationManager.SignIn(id);

The above code creates the set of claims to represent the identity of the user and creates a ClaimsIdentity from the claims. Note the second parameter to the ClaimsIdentity constructor — this indicates the type of authentication. In the OWIN authentication middleware, this authentication type must match that of the middleware being targeted. So since this code is presumably trying to issue a cookie, then this value must be the same as the name we assigned to the cookie middleware from the ConfigureAuth initialization code from above.

Once the ClaimsIdentity is created, we then access the OwinContext which has the AuthenticationManager. We use its SignIn API passing the ClaimsIdentity. This then matches the authentication type to the corresponding authentication middleware and since we match the cookie authentication middleware, a cookie is issued that contains the claims of the ClaimsIdentity.

An additional option on the SignIn API is to pass a AuthenticationProperties object. This has an IsPersistent property that indicates if the cookie is to be persistent.

Visual Studio 2013 templates and ASP.NET Identity

The VS2013 templates use the new ASP.NET Identity system to obtain the claims for the user. In the templates you will see this being performed by the UserManager’s CreateIdentityAsync API. Additionally, the MVC and WebForms templates provide many helper methods that encapsulate accessing and calling into the authentication manager.

Protecting the cookie

As a side note, the contents of the cookie are protected as you’d expect (signed and encrypted). This protection is by default, which is good. There is yet another security setting, though, that requires attention: SSL. By default (presumably for simplicity and ease of development) the cookie is only issued with the secure flag (i.e. require SSL) if the incoming request is SSL. This is an important setting to change when you release your application to production. This setting is configured with an enum:

public enum CookieSecureOption
{
   SameAsRequest,
   Never,
   Always
}

and would be done with this configuration change (notice the CookieSecure flag):

public void ConfigureAuth(IAppBuilder app)
{
   app.UseCookieAuthentication(new CookieAuthenticationOptions
   {
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
      LoginPath = new PathString("/Account/Login"),
      CookieSecure = CookieSecureOption.Always
   });
}

Other cookie configuration

There are two other settings of particular interest on the CookieAuthenticationOptions that might be familiar: ExpireTimeSpan and SlidingExpiration. The expiration allows the application to indicate how long the cookie is valid, and the sliding flag allows the expiration to be renewed as the user remains active within the application. The default for the expiration is 14 days and the default for the sliding flag is true.

Cookie authentication

So now that we have a cookie issued to the browser, upon subsequent requests the cookie will be sent and the cookie middleware must authenticate the request. The cookie middlware looks for the cookie name it issued (again from the name we assigned to the cookie middleware). If the cookie is absent, then it does nothing. If the cookie is present, then the cookie middleware reads and validates the cookie, and then if validated unpacks the claims contained therein and creates a ClaimsIdentity and sets this object into the OWIN context. Any downstream code could then use this OWIN API to determine the caller’s identity:

OwinContext ctx = Request.GetOwinContext();
ClaimsPrincipal user = ctx.Authentication.User;
IEnumerable<Claim> claims = user.Claims;

Of course, the ASP.NET APIs also work (Page.User, Controller.User) as well as the IIS host approaches (HttpContext.User, Thread.CurrentPrincipal and ClaimsPrincipal.Current).

Logout

Logging a user out is quite simple — there’s an API on the OWIN authentication manager called SignOut, which removes the cookie:

var ctx = Request.GetOwinContext();
var authenticationManager = ctx.Authentication;
authenticationManager.SignOut();

Fin

I hope this helps to understand the new OWIN cookie authentication middleware in .NET 4.5.1 and Visual Studio 2013.

44 Comments leave one →
  1. October 25, 2013 1:11 am

    Reblogged this on http://www.leastprivilege.com.

  2. November 5, 2013 4:40 pm

    Thanks. This article has helped me understand how the OWIN authentication works. I have a question. So if we get a claim from specifying scopes like “user_birthday” from “facebook” where do we hook that into the claims?

  3. Venki permalink
    November 7, 2013 9:35 am

    Thank You Very Much .. This helped me a lot ..

  4. November 8, 2013 10:25 am

    Actually, this helped a lot. I notice though that after the SignIn step. The code immediately shows the user is Authenticated.

    However, after I then redirect another page; the the Authenticated flag becomes false — appears the entire context gets lost.

  5. Dmitrij permalink
    November 29, 2013 10:24 am

    Hi Brock,
    I am using Google and Facebook authentication providers from the sample project from VS 2013 and have found a problem when I have successfully logged-in with Google or Facebook account and after that I choose log off, and try to log-in again with the same provider no Username and Password from another Google or Facebook account is asked.
    I am remaining in the same previous logged-in account.

    Could you help how to show the google/facebook sign-in page every time when I select Google/Facebook login?

    • December 7, 2013 3:32 pm

      This is because those providers are using OAuth2 and that’s not an authentication protocol and as such there’s no concept of forcing re-authentication. Now, those providers might have customized their implementations to allow this sort of feature, but that’s provider specific. You’d have to go read their docs to see if they support it and then configure the middleware to pass the custom param.

  6. Max permalink
    December 5, 2013 7:25 pm

    This was very helpful to implement cookie auth for the webapp version of a WebApi project, thank you so much!

  7. January 2, 2014 11:50 am

    Is it possible to share the Owin Forms Authentication across different virtual directories/applications?

    • January 4, 2014 10:51 am

      Sure, you just need to make sure you have the same verification logic and key. In OWIN this component is normally provided by the host, and in IIS this uses the machine key. In other hosts you’d need to configure it.

      • May 9, 2014 6:30 pm

        Hi Brock,

        Would you be able to provide a bit more detail on what is needed to accomplish this. I’ve been unable to get two apps on the same domain in visual studio 2013 running locally to use the same cookie. The identity project issues the cookie without problems, but it’s not accepted by the other app, the cookie domain is localhost and the path ‘/’.

        Thanks,

  8. G.bes permalink
    January 6, 2014 2:28 pm

    Great article! Thanks.

    I’m wodering if there’s a way to run a piece of code and signout the user automatically after a predefined timeout?

    • January 6, 2014 3:29 pm

      From the server you can’t just reach out to the browser to revoke a cookie. So no, there’s nothing like this built in.

      • G.bes permalink
        January 7, 2014 1:49 am

        Thanks for your reply. If i want to implement a home made time-out mechanism wich starting point would you suggest? Which approch is suitable for this scenario?

  9. January 16, 2014 4:31 am

    This article is great. I have been so confused coming back to .NET and expecting the old Forms Auth logic.

    Is there a way to change the LoginPath that is set to the cookie after it has been created?

    • January 16, 2014 8:17 am

      There’s a property on the CookieAuthenticationOptions called CookiePath — is this what you’re looking for?

  10. Tai permalink
    February 22, 2014 12:42 am

    Brock,

    I would be lost if it wasn’t for all your posts on this subject. So here is a point of some confusion. Does this replace WIF’s session authentication module? Was it like we got a new tech for auth with WIF and now this is new new?

    Also, I can’t find info ANYWHERE on how you secure a resource (like a webpage) with a claim. Is there some equivalent in OWIN to but for claims. Is it some combination with WIF and OWIN? Or is this stuff just so new its only good for authentication, in which case… REALLY?? Who makes web pages without authorization?

    Thanks!

    • February 22, 2014 8:58 am

      Yes, the new Katana cookie MW is a SAM replacement. Also, there’s a new WS-Fed MW that was just released (as beta) this week. Katana is the way forward for anything that used to be done as a HttpModule in IIS.

      As for “securing a resource” not sure what you mean. Each framework (SignalR, Web API, etc) has their own helpers for authorization. And ultimately, since we’re working over HTTP, the way you restrict access is to issue a 401 status code from your code.

      • Tai permalink
        February 22, 2014 1:39 pm

        Thanks for the reply. By securing a resource I mean how do I lock down something like a web page or folder by claim (I would think role is dead). Say I have an admin area only for admins, there used to be simple web.config configuration to say the admin folder is only for role admin.

        I can’t find the equivalent with OWIN. Thanks

        • February 22, 2014 1:45 pm

          Let me respond by asking how you did it with roles?

          • Tai permalink
            February 23, 2014 2:52 am

            Sure. So using forms authentication and the roles membership provider I simply add this configuration to the web.config:

            This has always been straight forward. I would expect that we could now lock down a page or directory by a claim instead of a role. Or maybe I’m just thinking that claims replaces roles and that I can create a claim for a permission like Admin add it to my claims list and then indicate that this directory only allows access if you have that claim. Or am crazy and claims have nothing to do with permissions and we still need roles and the above just works, although who would make the cookie for the roles? Thanks!

          • Tai permalink
            February 23, 2014 2:56 am

            The blog stripped my config example here is another try:

            location path=”administration”
            system.webServer
            security
            authorization
            clear
            add accessType=”Allow” roles=”admin”
            authorization
            security
            system.webServer
            location

          • February 23, 2014 9:21 am

            Well, my point in asking was to illustrate that these still exits. You can also build your own infrastructure to do claims-based checks and when the user fails authorization you can return 401 status code. Also, .NET has some built in with its ClaimsAuthorizationManager and we have some helpers with IdentityModel: https://github.com/thinktecture/Thinktecture.IdentityModel

          • Tai permalink
            February 23, 2014 12:41 pm

            Ok, so then i’m not going completely crazy. OWIN is half of the solution, authentication. So MS is really leaving authorization out and I’m now falling back to an HTTP Module again with ClaimsAuthorizationManager. So at this point I’m OWIN for authentication and WIF for Authorization. What’s the benefit of using OWIN at all, why don’t I just also use WIF’s SessionAuthenticationModule and ClaimsAuthorizationModule and have a full solution. Is OWIN providing any functionality that I’m not just getting already with WIF?

          • February 23, 2014 2:32 pm

            OWIN is a tough sell if you don’t care about host independence since it’s a new stack to learn. But eventually it will allow for faster apps. Also, it’s for Microsoft’s benefit so that they can build one library (security for example) that works across all their frameworks (Web API, ASP.NET, SignalR, etc).

  11. March 10, 2014 1:39 pm

    Good stuff – I’m fairly new to the new .NET Identity model (I know only the basics). I have a scenario where every user is associated to possibly many organizations. Instead of querying for this every time (a lot), I feel this might be a good place to associate a users organizations with the user (using a claim). Is there a certain claim type I should use? Should I just add these claims in the registration pipeline? Does this scenario even make sense for adding claims?

    • March 10, 2014 2:38 pm

      Yes, this sounds like a claim — it’s identity info about the user.

  12. valdis permalink
    April 17, 2014 1:06 am

    Great

  13. Zen permalink
    April 25, 2014 11:12 am

    Hi Brock,

    Thanks for blogging about the OWIN Cookie Authentication Middleware.

    I have a quick question for you. Is there a way to intercept the events before and after the OWIN Cookie Middlewear reads the cookie and creates the ClaimsIdentity object?

    Thanks!

    Zen

    • April 25, 2014 2:17 pm

      Yes, the CookieAuthenticationOptions class has a Provider property — it’s an instance of the CookieAuthenticationProvider class: http://msdn.microsoft.com/en-us/library/microsoft.owin.security.cookies.cookieauthenticationprovider%28v=vs.113%29.aspx and it has properties which are delegates you can subscribe to. This allows you to validate the cookie as it comes into the application (OnValidateIdentity). In this callback you can reject or replace the identity.

      • Zen permalink
        April 25, 2014 11:18 pm

        Thanks Brock for your prompt reply. I might be wrong, but I think that OnValidateIdentity runs on only predefined intervals specified by validateInterval argument.

        What I am interested to know is, the code that runs on every request and reads the authentication cookie, deserializes, creates an instance of ClaimsIdentity (if it is found to be valid) and attaches it to the HttpContext.

        Any ideas?

        Thank!

        Zen

        • April 29, 2014 9:36 pm

          Umm, no, as far as I can tell the validate event runs on each request, assuming the cookie is valid (decrypts and is not expired).

  14. May 27, 2014 3:00 am

    For single sign on there is a bug in asp.net mvc templates available. For signle sign on to work using machine key, One need to add two MVC project with web APi option checked . Then hosted the projects on iis and try single sign on by using the authorize attribute on WEBAPi functions. It is working with me . But i am not able to attain the same behavior with only WEB API based project selection. I am of view that there are bugs in the project selection and they should be address .

  15. June 4, 2014 6:00 am

    Very informative ..thanks. I think there is a small typo that you might want to fix. “By default (presumably for simplicity and ease of development) the cookie is only issued with the secure flag (i.e. require SSL)***is*** the incoming request is SSL” ..’is’ needs to be replaced with “if”. Thanks.

  16. KARTHIKEYAN N R permalink
    July 5, 2014 3:07 am

    Dear Brockallen,

    I switched over from SAMs to the new OWIN authentication.. I love the OWIN features and your article guided me to implement the same in my project without any trouble. Thanks for sharing and will add your name and blog in my thanks page as gratitude.

    • KARTHIKEYAN N R permalink
      July 8, 2014 5:27 am

      One problem I am facing… After logout using browser back button I can retain the previous session.. I used the following code to clear the session and all folks..

      Dim ctx2 = Request.GetOwinContext()
      Dim authenticationManager = ctx2.Authentication
      authenticationManager.SignOut()

      Session.Clear() ‘clear session
      Session.Abandon() ‘//Abandon session
      Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(-1))
      Response.Cache.SetCacheability(HttpCacheability.NoCache)
      Response.Cache.SetNoStore()
      Response.Redirect(“Login”)
      Return (Nothing)

      But Logout is possible only if close the browser. Also request you to provide a solution to get rid of back button as in gmail.com

Trackbacks

  1. Decaying Code | Community Update November 28th 2013 – Custom OAuth, WebAPI, and more
  2. A primer on external login providers (social logins) with OWIN/Katana authentication middleware | brockallen
  3. Hilfreiche Owin Links | Norbert Eder
  4. Decaying Code | Community Update 2014-05-06 – #backbonejs, #microsoftazure, #webapi, #elasticsearch
  5. Using OWIN Authentication Middleware WITH VS2012 And ASP.NET MVC-4 | Prerak Kaushik

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: