Mar 19, 2014

Posted in , , ,

FREE ASP.NET MVC 5 Germany Hosting - HostForLIFE.eu ASP.NET MVC 5 Authentication Breakdown

I've been inspecting the new bits of ASP.NET MVC 5 and trying to make sense of the new paradigm that me, as .NET developer, is going to be working in. This new shift will probably be known as the Open Web Inerface for .NET era or more succinctly the OWIN era. OWIN is a middleware implementation for .NET that will allow developers, like me, to hook into a deeper pipeline to perform tasks like logging, exception handling, authentication, and more that my imagination can't contemplate just yet. This post isn't about OWIN and the possibilities, but it is about the new authentication found in ASP.NET MVC 5.

http://hostforlife.eu/European-ASPNET-MVC-4-Hosting

Registering the Middleware

I started by creating a new ASP.NET MVC 5 project using the existing templates that come with Visual Studio 2013 and picked the individual user accounts option for authentication. This means my user information will be stored locally in a data storage. The default data storage is SQL Server. Looking in the App_Start folder, I find Startup.Auth.cs. The file contents looks like this:
    public partial class Startup
    {
        // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
        public void ConfigureAuth(IAppBuilder app)
        {
            // Enable the application to use a cookie to store information for the signed in user
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login")
            });
            // Use a cookie to temporarily store information about a user logging in with a third party login provider
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // Uncomment the following lines to enable logging in with third party login providers
            //app.UseMicrosoftAccountAuthentication(
            //    clientId: "",
            //    clientSecret: "");

            //app.UseTwitterAuthentication(
            //   consumerKey: "",
            //   consumerSecret: "");

            //app.UseFacebookAuthentication(
            //   appId: "",
            //   appSecret: "");

            //app.UseGoogleAuthentication();
        }
    } 
I also found this in the web.config of the application.
<system.web>
    <authentication mode="None" />
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.webServer>
    <modules>
      <remove name="FormsAuthenticationModule" />
    </modules>
  </system.webServer> 
 
With these two files, I realize that the old forms authentication model has been replaced by the OWIN pipeline. Diving deeper into the calls found in the startup app, I also realize that each of the calls just registers a new middleware class to handle that particular auth provider. This is the google registration.

http://www.hostforlife.eu/European-ASPNET-Hosting-Free-Trial
public static IAppBuilder UseGoogleAuthentication(this IAppBuilder app, GoogleAuthenticationOptions options)
    {
      if (app == null)
        throw new ArgumentNullException("app");
      if (options == null)
        throw new ArgumentNullException("options");
      app.Use((object) typeof (GoogleAuthenticationMiddleware), (object) app, (object) options);
      return app;
    }
nothing really fancy here, just instantiating the middle ware, then registering it with the application. The next step is to use the middleware.

AccountController

The AccountController is where ASP.NET MVC 5 gets confusing, because there is the noise introduced by the UserManager implementation. Ignore this, it is simply a Entity Framework implementation allowing you to save user information. I would most likely remove this, as I don't use Entity Framework myself.
The more interesting part of the AccountController is the IAuthenticationManager property.
private IAuthenticationManager AuthenticationManager
{
    get
    {
        return HttpContext.GetOwinContext().Authentication;
    }
} 
 
The IAuthenticationManager is being pulled from the OWIN implementation built on top of ASP.NET. When I start looking for uses of this property, I find the next generation of the things I've grown fond of with the FormsAuthentication class: SignIn and SignOut.
// Sign In
 AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
// Sign Out
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
The interesting part, is now I can create cookies with the distinction of whether they are internally generated, or generated by a third party provider: Twitter, Facebook, or Google.
The final piece of this is the ChallengeResult class, which looks to be optional to implement.
private class ChallengeResult : HttpUnauthorizedResult
{
    public ChallengeResult(string provider, string redirectUri) : this(provider, redirectUri, null)
    {
    }

    public ChallengeResult(string provider, string redirectUri, string userId)
    {
        LoginProvider = provider;
        RedirectUri = redirectUri;
        UserId = userId;
    }

    public string LoginProvider { get; set; }
    public string RedirectUri { get; set; }
    public string UserId { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
        if (UserId != null)
        {
            properties.Dictionary[XsrfKey] = UserId;
        }
        context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
    }
}
The only thing it does, is make a call to the IAuthenticationManager.Challenge to trigger the challenge built into the OWIN pipeline. This will redirect to a login page for the external auth providers.

Summary

All I need to get authentication working using OWIN is the following:
  • The contents of App_Start/Startup.Auth.cs.
  • The **IAuthenticationManager*.
  • Optionally, ChallengeResult, which is a nice helper Result.
How they work together:
  1. The authentication providers are registered with the app in startup.
  2. Cookies are handled by OWIN and the middleware.
  3. Each external auth provider's login challenge can be triggered using the ChallengeResult.
  4. Cookies are managed using IAuthenticationManager.SignIn and IAuthenticationManager.SignOut.
  5. Auth is based on Claims.
So after dissecting the start template, I found out what is basically important and what is just "helpful" stuff Microsoft gives me out of the box. There are definitely things that are still foggy to me, but I think I have a good understanding now of what it takes to do authentication in the OWIN era of ASP.NET MVC.

0 comments:

Post a Comment

thanks for your comment!