Pergunta

So I am currently using a ViewBag set in the login to determine if they can see admin only stuff. This is done this way because Roles.CreateRole, Membership.CreateUser and Roles.AddUserToRole is disabled because we use ModelFirst ASP.net.

public ActionResult Login(LoginModel model, string returnUrl)
    {
        ViewBag.Admin = false;
            if (model.IsValid(model.UserName, model.Password))
            {
                ViewBag.Admin = (bool)model.currentLoggedInEmployee.IsAdmin;
                FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
                return RedirectToAction("Index", "Home");
            }
            else
            {
                ModelState.AddModelError("", "Login data is incorrect!");
                return View(model);
            }
    }

Then we simply use:

   @if (ViewBag.Admin == true) {
        <li>@Html.ActionLink("Administration", "Index", "Administration")</li>
   }

to only show these buttons to admins. This works.

Now what we want, is to make sure only administrators can run some functions, by doing something similar to the normal

[Authenticate(Roles="Admin")]
[HttpPost]
    public ActionResult Create(FormCollection collection)
    {
        // TODO: Add insert logic here
    }

But because we don't have any "Roles" we can not do it like this. We need to use the ViewBag.Admin value to authorize people to use these functions. Question is, how can this be done?

Foi útil?

Solução

I would recommend rolling your own AuthorizeAttribute and from there you can determine whether or not the current logged in user is an admin or not.

When you create your authentication cookie add some additional information (i.e. the admin flag) e.g.

public ActionResult Login(LoginModel model, string returnUrl)
{
    if (model.IsValid(model.UserName, model.Password))
    {
         var ticket = new FormsAuthenticationTicket(1,
             model.UserName,
             DateTime.Now,
             DateTime.Now.AddMinutes(30),
             model.RememberMe,
             model.currentLoggedInEmployee.IsAdmin, // user data
             FormsAuthentication.FormsCookiePath);

         // Encrypt the ticket.
         string encTicket = FormsAuthentication.Encrypt(ticket);

         // Create the cookie.
         Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));

         // Redirect back to original URL.
         return RedirectToAction("Index", "Home");
    }
    else
    {
        ModelState.AddModelError("", "Login data is incorrect!");
        return View(model);
    }
}

Create a custom authorize attribute to authenticate the logged in user against the role e.g.

public class AdminOnlyAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext.Current.User.Identity.IsAuthenticated)
        {
            var ticket = ((FormsIdentity)User.Identity).Ticket;
            return (bool)ticket.UserData;
        }
        else
        {
             return false;
        }
    }
}

Then decorate your action as:

[AdminOnly]
[HttpPost]
public ActionResult Create(FormCollection collection)
{
    // TODO: add insert logic here
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top