27

I have an internal web app being built in ASP.NET 4. We are stuck with using an authentication API built by another team. If a user to the site is authenticated successfully for the site I would like to give them access to the entire site.

In ASP.NET WebForm days I just used to keep a custom User object in session. If that object was null I knew the user wasn't authenticated. Is there a similar but improved method for this in MVC. I don't want to have to build my own provider of the ASP.NET Membership model if possible. What is the simplest way of doing this?

7
  • 1
    Can you not just set the authentication ticket manually after your call to your legacy API? Commented Sep 3, 2013 at 14:09
  • 1
    If the FormsAuthenticationTicket is set, you can use Request.IsAuthenticated and User.Identity to determine whether the user is logged in. Also the Authorize attribute will work. Commented Sep 3, 2013 at 14:10
  • 3
    FYI, handling authentication in session is a very bad idea, it's insecure (cookie is not encrypted and easily stolen), and prone to failure as session can be recycled at any time. Use FormsAuthentication instead Commented Sep 3, 2013 at 14:31
  • Great feedback. Thanks TheKingDave, Henk, Mystere Commented Sep 3, 2013 at 20:04
  • 1
    Sometimes the solution is on another question, someone already did a very flexible solution here on on stackoverflow without need of hard coded role name , there is the complete code: stackoverflow.com/questions/9043831/… Commented Jan 16, 2014 at 16:54

5 Answers 5

45

You can use Forms Authentication in conjuction with Authorize attibute as follows,

To restrict access to a view :

Add the AuthorizeAttribute attribute to the action method declaration, as shown below,

[Authorize]
public ActionResult Index()
{
    return View();
}

Configuring Forms Authentication in web.config

<authentication mode="Forms">
     <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>

Login Post Action: Set Authentication cookie if user is valid

[HttpPost]
public ActionResult Login(User model, string returnUrl)
{
        //Validation code

        if (userValid)
        {
             FormsAuthentication.SetAuthCookie(username, false);
        }
}

Log off Action:

public ActionResult LogOff()
{
    FormsAuthentication.SignOut();
    return RedirectToAction("Index", "Home");
}
Sign up to request clarification or add additional context in comments.

3 Comments

Do I have to put [Authorize] on every Controller method in my entire app? I only want to open up two controller methods to anonymous users (~/Account/Login GET and POST). Seems like there should be a better way. Do this require a filter? custom attribute? Thanks for your help. +1
Why can't the new ASP Identity be as simple as FormsAuthentication? asp.net/identity
5

You probably want to have a custom authorization filter. Here's an example: Custom filters in MVC. You can then apply this filter globally on app start (using RegisterGlobalFilters).

public class LegacyAuthorize : AuthorizeAttribute
{
  public override void OnAuthorization(HttpActionContext actionContext)
  {
    if (HttpContext.Current.Session["User"] == null)
      base.HandleUnauthorizedRequest(actionContext);
  }
}

Then in your global.asax you'd have something like this:

GlobalFilters.Filters.Add(new LegacyAuthorize());

1 Comment

Overriding the Authorize attribute can be dangerous especially if only validating session. Session Id is not re-generated, which can lead to session hijack via XSS etc. blog.securityps.com/2013/06/… and support.microsoft.com/en-us/kb/899918
4

You can try with something like this:

FormsAuthentication.SetAuthCookie(username, rememberMe);

to set the cookie for authenticated user, then just use the [Authorize] attribute on the Controller or Action that need authentication.

Try googling on the subject for further info, you will find a lot of stuff on authentication and authorization in MVC.

Comments

1

Everything you could do in forms you can do in MVC, just set the session variable in the controller login action.

Or you can do this: In the login action add formsauthentication.setauthcookie("username")

After this any action with the [Authorize] keyword will allow the current user in.

Comments

-2

You can do the Session Authentication by simply putting a session variable value when the login is successful. Eg

public ActionResult Index(Models.Login login)
    {
        if (ModelState.IsValid)
        {
            Dal.Login dLogin = new Dal.Login();
            string result = dLogin.LoginUser(login);
            if (result == "Success")
                Session["AuthState"] = "Authenticated";
        }
        return View();
    }

Now the trick is that you should have a common layout page of all the views to which you have to check for authentication. And in this layout page just do a razor check like this -

<body>
    @if (Session["AuthState"] != "Authenticated")
    {
        Response.Redirect("~/login");
    }
    // other html
</body>

I have been using this method in my application admin panel.

1 Comment

Just a heads up that this method is dangerous and can result in a session fixation or session hijack attack. The session id is never updated. See this article for a quick explanation of the downsides. tl;dr; you need an authentication cookie that is unique to a logged in session and ideally tied to the session. blog.securityps.com/2013/06/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.