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?

huMpty duMpty
  • 14,346
  • 14
  • 60
  • 99
BuddyJoe
  • 69,735
  • 114
  • 291
  • 466
  • 1
    Can you not just set the authentication ticket manually after your call to your legacy API? – TheKingDave Sep 03 '13 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. – Henk Mollema Sep 03 '13 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 – Erik Funkenbusch Sep 03 '13 at 14:31
  • Great feedback. Thanks TheKingDave, Henk, Mystere – BuddyJoe Sep 03 '13 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: http://stackoverflow.com/questions/9043831/authorizeattribute-with-roles-but-not-hard-coding-the-role-values/9048151#9048151 –  Jan 16 '14 at 16:54
  • @BuddyJoe, I'm doing the same thing. Do you mind if I ask what solution you went with? – RayLoveless Apr 11 '16 at 22:21
  • @HenkMollema I am using `FormsAuthenticationTicket`, but I could not use `User.Identity` and `Authorize` is not working – Ikelie Cyril Jun 30 '18 at 18:00

5 Answers5

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");
}
Jatin patil
  • 4,252
  • 1
  • 18
  • 27
  • 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 – BuddyJoe Sep 10 '13 at 21:29
  • 3
    In this case have a look here http://blogs.msdn.com/b/rickandy/archive/2011/05/02/securing-your-asp-net-mvc-3-application.aspx – Jatin patil Sep 11 '13 at 05:16
  • Why can't the new ASP Identity be as simple as `FormsAuthentication`? https://www.asp.net/identity – Luke T O'Brien Jul 27 '17 at 11:37
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());
volpav
  • 5,090
  • 19
  • 27
  • 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. http://blog.securityps.com/2013/06/session-fixation-forms-authentication.html and https://support.microsoft.com/en-us/kb/899918 – PJH Aug 11 '16 at 18:07
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.

Daniele
  • 1,938
  • 16
  • 24
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.

Solmead
  • 4,158
  • 2
  • 26
  • 30
-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.

yogihosting
  • 5,494
  • 8
  • 47
  • 80
  • 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. http://blog.securityps.com/2013/06/session-fixation-forms-authentication.html – PJH Aug 11 '16 at 18:02