ASP.NET MVC Forms Authentication + Authorize Attribute + Simple Roles

Kevin picture Kevin · Sep 6, 2009 · Viewed 60k times · Source

I'm trying to add simple Authentication and Authorization to an ASP.NET MVC application.

I'm just trying to tack on some added functionality to the basic Forms Authentication (due to simplicity and custom database structure)

Assuming this is my database structure: User: username password role (ideally some enum. Strings if need be. Currently, user only has ONE role, but this might change)

High Level Problem: Given the above database structure, I would like to be able to do the following:

  • Simple Login using Forms Authentication
  • Decorate my actions with: [Authorize(Roles={ MyRoles.Admin, MyRoles.Member})]
  • Use roles in my Views (to determine links to display in some partials)

Currently, all I'm really sure of is how to Authenticate. After that I'm lost. I'm not sure at which point do I grab the user role (login, every authorization?). Since my roles may not be strings, I'm not sure how they will fit in with the User.IsInRole().

Now, I'm asking here because I haven't found a "simple" accomplish what I need. I have seen multiple examples.

For Authentication:

  • We have simple user validation that checks the database and "SetAuthCookie"
  • Or we override the Membership provider and do this inside of ValidateUser In either of these, I'm not sure how to tack on my simple user Roles, so that they work with the: HttpContext.Current.User.IsInRole("Administrator") Furthermore, I'm not sure how to modify this to work with my enum values.

For Authorization, I've seen:

  • Deriving AuthorizeAttribute and implementing AuthorizeCore OR OnAuthorization to handle roles?
  • Implementing IPrincipal?

Any assistance would be greatly appreciated. However, I fear I may need a lot of detail, because none of what I've Googled seems to fit with what I need to do.

Answer

yinner picture yinner · Feb 26, 2010

I think I've implemented something similar.
My solution, based on NerdDinner tutorial, is following.

When you sign the user in, add code like this:

var authTicket = new FormsAuthenticationTicket(
    1,                             // version
    userName,                      // user name
    DateTime.Now,                  // created
    DateTime.Now.AddMinutes(20),   // expires
    rememberMe,                    // persistent?
    "Moderator;Admin"                        // can be used to store roles
    );

string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);

Add following code to Global.asax.cs:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie == null || authCookie.Value == "")
        return;

    FormsAuthenticationTicket authTicket;
    try
    {
        authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    }
    catch
    {
        return;
    }

    // retrieve roles from UserData
    string[] roles = authTicket.UserData.Split(';');

    if (Context.User != null)
        Context.User = new GenericPrincipal(Context.User.Identity, roles);
}

After you've done this, you can use [Authorize] attribute in your controller action code:

[Authorize(Roles="Admin")]
public ActionResult AdminIndex ()

Please let me know if you have further questions.