FormsAuthentication object obsolete [using MVC5]
Asked Answered
W

2

13

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?

Waxwork answered 11/1, 2014 at 11:46 Comment(0)
S
6

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!

Snooze answered 12/1, 2014 at 18:14 Comment(2)
Thanks for your reply Levi. In that case, what is the preferred way to achieve simple authentication such as in my example, then? Do you know of any white papers or articles that offer up any alternatives, or is the recommended way to implement membership and your own storage and hashing algorithms? I have done this many times in more complex systems, but I feel it's overkill in this particular instance.Waxwork
If you feel it is overkill for this particular instance, ignore the warning (or suppress it via #pragma warning disable). You can absolutely continue to use that original method if it's suitable for your scenario. If you want something more secure, you can use Crypto.HashPassword msdn.microsoft.com/en-us/library/… and Crypto.VerifyHashedPassword msdn.microsoft.com/en-us/library/… from the System.Web.Helpers.dll assembly.Snooze
V
6

OWIN is not just about security. It is a standard that defines the interfaces between an application framework (ASP.NET MVC) and a web server (IIS). It is a new layer of abstraction Microsoft defined to let .NET developers write applications that are host agnostic, i.e. not dependent on IIS.

OWIN architecture is a pipeline that consists of multiple middleware components. In MVC5, security has been rewritten from scratch as an OWIN middleware component. If this does not work for you and you want to roll your own password verification routine, you can implement your own security middleware. Here is a post describing how to do it.

If you don't want to go that far, this post shows how to rely on the built in authentication framework without the Membership

Everything Levi mentioned is still valid, though. You want to be careful with your own hashing/storage mechanism and pick a good hashing algorithm.

Here some more background info on OWIN security midddleware implemented by Microsoft.

Valentinavalentine answered 13/1, 2014 at 16:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.