FormsAuthentication object obsolete [using MVC5]

Spikeh picture Spikeh · Jan 11, 2014 · Viewed 8.6k times · Source

I'm using the following code in an MVC5 site:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel loginModel) {
    if (ModelState.IsValid) {
        var authenticated = FormsAuthentication.Authenticate(loginModel.UserName, loginModel.Password);
        if (authenticated) {
            FormsAuthentication.SetAuthCookie(loginModel.UserName, true);
            return RedirectToAction("AdminPanel");
        }
        ModelState.AddModelError("", "The username and password combination were incorrect");
    }
    return View(loginModel);
}

Which throws up the following warning:

System.Web.Security.FormsAuthentication.Authenticate(string, string)' is obsolete: 'The recommended alternative is to use the Membership APIs, such as Membership.ValidateUser. For more information, see http://go.microsoft.com/fwlink/?LinkId=252463.'

First a disclaimer - I'm one of those developers that likes to keep up to date with things, and I prefer to avoid warnings in VS entirely. However, in this particular instance, I am using extremely primitive authentication, which comes directly from the web.config, as follows:

<authentication mode="Forms">
    <forms loginUrl="~/account/login" timeout="2880" slidingExpiration="true" name=".ASPXFORMSAUTH">
        <credentials passwordFormat="SHA1">
            <user name="MyUserName" password="a-big-long-password-hash"/>
        </credentials>
    </forms>
</authentication>

There is absolutely no further login requirements in this project - using a database is overkill, and there's no need for distributed login; basically, storing the details in web.config is the most ideal solution, and there will probably only be one user per application. I will no doubt abstract the authentication code out from the controller (using DI / IoC), but I am still intending to use the FormsAuthentication object to authenticate against the details in web.config.

While I am fully aware of membership providers, DotNetOpenAuth and the new (but pretty horrible imo) OWIN based authentication model, the above code is more than adequate.

First question - Why has FormsAuthentication been made obsolete when this is a perfectly valid use case? I understand that FormsAuthentication is a sealed black box, is hard to test, and the code behind it is domain specific, but in this particular instance (where I want to read details directly from the section of the web.config), it seems madness to write a membership provider or a custom authentication service?

Second Question - Unless I'm missing something, the new OWIN model is for distributed authentication, and is not suitable for a role based, enterprise level security system. From the many blog posts, white papers and SO posts I've read, it also seems like it's still incomplete. Am I right in my assumptions? Is OWIN the future of all security systems, or should I continue to write bespoke security systems more appropriate for my clients needs?

Answer

Levi picture Levi · Jan 12, 2014

To your first point, we obsoleted it because it is woefully inadequate by modern security standards. It uses a straight hash with no iteration, which means that anybody who accesses your Web.config can easily figure out what the original passwords were. But if you're willing to accept these risks, you can certainly continue using it going forward. Just suppress the warning and solider on with your original code.

To your second point, there is no relation whatsoever between any of this and OWIN.

Hope this clears it up!