Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC Role Authorization

I am trying to implement a role authorization mechanism which checks the roles of the current logged in user, if the user is in the right role, he/she is allowed, else display error view.

The problem is that when the user tries to access the below method in the controller, he does get into the RoleAuthorizationAttribute class and gets verfied but then the method in the controller is not executed.

Note : the user has the Client role

Controller method

[RoleAuthorization(Roles = "Client, Adminsitrator")]
    public ActionResult addToCart(int ProductID, string Quantity)
    {
        tempShoppingCart t = new tempShoppingCart();
        t.ProductID = ProductID;
        t.Username = User.Identity.Name;
        t.Quantity = Convert.ToInt16(Quantity);

        new OrdersService.OrdersClient().addToCart(t);
        ViewData["numberOfItemsInShoppingCart"] = new OrdersService.OrdersClient().getNoOfItemsInShoppingCart(User.Identity.Name);
        ViewData["totalPriceInSC"] = new OrdersService.OrdersClient().getTotalPriceOfItemsInSC(User.Identity.Name);
        return PartialView("quickShoppingCart", "Orders");
    }

Role Authentication class

[System.AttributeUsage(System.AttributeTargets.All,AllowMultiple = false, Inherited = true)]
public sealed class RoleAuthorizationAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {


        List<String> requiredRoles = Roles.Split(Convert.ToChar(",")).ToList();

        List<Role> allRoles = new UsersService.UsersClient().GetUserRoles(filterContext.HttpContext.User.Identity.Name).ToList();


        bool Match = false;

        foreach (String s in requiredRoles)
        {
            foreach (Role r in allRoles)
            {
                string rName = r.RoleName.Trim().ToString();
                string sName = s.Trim();
                if (rName == sName)
                {
                    Match = true;
                }
            }
        }

        if (!Match)
        {
            filterContext.Result = new ViewResult { ViewName = "AccessDenied" };
        }

        base.OnAuthorization(filterContext);

    }
}

Could you please tell me what I am doing wrong

like image 676
drinu16 Avatar asked Mar 28 '14 23:03

drinu16


1 Answers

Since I had the roles of the users in the database I had to check against the database so I included this method in the global.asax

protected void Application_AuthenticateRequest(object sender, EventArgs args)
    {
        if (Context.User != null)
        {
            IEnumerable<Role> roles = new UsersService.UsersClient().GetUserRoles(
                                                    Context.User.Identity.Name);


            string[] rolesArray = new string[roles.Count()];
            for (int i = 0; i < roles.Count(); i++)
            {
                rolesArray[i] = roles.ElementAt(i).RoleName;
            }

            GenericPrincipal gp = new GenericPrincipal(Context.User.Identity, rolesArray);
            Context.User = gp;
        }
    }

Then I could use the normal

[Authorize(Roles = "Client, Administrator")]

On top of the actionResult methods in the controllers

This worked.

like image 164
drinu16 Avatar answered Oct 01 '22 17:10

drinu16