Store/assign roles of authenticated users

Billy Logan picture Billy Logan · Nov 30, 2009 · Viewed 38.5k times · Source

I am upgrading a site to use MVC and I am looking for the best way to set up Authentication.

At this point, I have the log-in working off of Active Directory: validating a username and password, and then setting the Auth cookie.

How do I store the user's role information at time of log-in, in order for my controllers to see those roles as the user navigates through the site?

[Authorize(Roles = "admin")]

I have no problem getting a list of roles from Active Directory. I just don't know where to put them so that the controllers will see them.

Answer

David Glenn picture David Glenn · Dec 1, 2009

Roles are added to the IPrincipal of the HttpContext. You can create a GenericPrincipal, parse the list of roles in the constructor and set it as HttpContext.User. The GenericPrincipal will then be accessible through User.IsInRole("role") or the [Authorize(Roles="role")] attribute

One way of doing this (in C#) is to add your roles as a comma separated string in the user data parameter when creating your authentication ticket

string roles = "Admin,Member";
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
  1,
  userId,  //user id
  DateTime.Now,
  DateTime.Now.AddMinutes(20),  // expiry
  false,  //do not remember
  roles, 
  "/");
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,
                                   FormsAuthentication.Encrypt(authTicket));
Response.Cookies.Add(cookie);

Then access the role list from the authentication ticket and create a GenericPrincipal from your Global.asax.cs

protected void Application_AuthenticateRequest(Object sender, EventArgs e) {
  HttpCookie authCookie = 
                Context.Request.Cookies[FormsAuthentication.FormsCookieName];
    if (authCookie != null) {
      FormsAuthenticationTicket authTicket = 
                                  FormsAuthentication.Decrypt(authCookie.Value);
      string[] roles = authTicket.UserData.Split(new Char[] { ',' });
      GenericPrincipal userPrincipal =
                       new GenericPrincipal(new GenericIdentity(authTicket.Name),roles);
      Context.User = userPrincipal;
    }
  }