How to set custom authentication cookies?

Nov 5, 2014 at 9:04 AM
I'm building a custom ASP.NET Identity 2.0 implementation that uses our own data model, another ORM, other business logic, etc. By default, a user is logged in by setting the ApplicationCookie, after which the AuthorizeAttribute recognizes the cookie and logs the user in. For our own implementation, I want to add more ways to log in. For example:
  • Impersonation
  • Password reset token
  • Google Authenticator (two-factor)
  • SMS (two-factor)
In all these scenarios the user must be logged in, but what actions the user is allowed to perform depends on the way he logged in. For example: when the user logged in using a 'password reset token', he may change his password but not do anything else. When the user logged in with 'username + password', he may do basically everything, except for the actions that need a higher permission level (where the two-factor methods come in play). In order to do this, I want to build a custom AuthorizeAttribute that checks what login method was used, and then decides whether the user may perform the action or not.

The problem I'm facing is that I can set other cookies than ApplicationCookie (e.g. the TwoFactorCookie that is being set by going through the SMS process), but those cookies are not recognized as authentication cookies. Thus, when I have a TwoFactorCookie, I can't use that cookie to log in. Only having an ApplicationCookie results in a log in.

The issues I'm struggling with:
  • Do I always need to use ApplicationCookie to log in or can I use custom cookies to log in as well (so for example I can log in using ApplicationCookie, TwoFactorCookie and XYZCookie?
  • Should I have different cookies for each authentication method or should I have only 1 cookie and store the authentication method/type in a different way (for example in a Claim)?
  • If I should use different cookies, should I also write custom authentication middleware for each authentication method/type or can I use the default CookieAuthenticationMiddleware? As far as I know, the only thing that has to be done is set a cookie, and flag it with the correct authentication method so I can see how the user was logged in.
Edit:

As per Hao Kung's suggestion (http://stackoverflow.com/a/26664061/3828723) I made a couple of extension methods that look like this:
public static void UseSmsSignInCookie(this IAppBuilder app, TimeSpan expires)
{
    if (app == null)
        throw new ArgumentNullException("app");

    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = ApplicationAuthenticationTypes.Sms,
        AuthenticationMode = AuthenticationMode.Passive,
        CookieName = CookiePrefix + ApplicationAuthenticationTypes.Sms,
        ExpireTimeSpan = expires,
    });
}
I try to log someone in by calling AuthenticationManager.SignIn with a custom ClaimsIdentity that has my custom AuthenticationType (SMS). This doesn't work though: after calling SignIn, the result of HttpContext.Current.User.Identity.AuthenticationType still equals ApplicationCookie. The cookie has been set as expected though.

Does anyone have an idea what I'm missing?