azza idz
azza idz

Reputation: 663

Best practice to allow/deny user to call Controller actions depending on role rights

I have a role system where the Admin can create new roles and grant Read, Write, Edit and Delete rights based on the page menu (each page menu has it's own controller) then assign that role to the user.

Users can also have multiple roles but i got that covered. The only problem I am facing is this: since Role assigning can be done dynamically from within the application i can't use the [Authorize(Roles = Role.Admin)] attribute over controller actions.

Instead i was thinking of creating [Read], [Write], [Edit] and [Delete] attributes that i would put over the actions to let me know what that action is for and then allow or deny users to call that action.

Would this be the correct approach? What would i need to have in those custom attributes and how would i allow/deny user to call them? Anyone have any similar experience?

Let's say i have Home and Admin controller and Role1 and Role2 with following rights:

enter image description here

Would something like the above approach works? How do I define custom access for controller actions?

I want to avoid having all the actions in the database and simplify the administration on the site.

In this way administration can be done on R/W/E/D flags on controller level instead of Role1 can all Home/Index, Home/GetRecords etc... action level.

Upvotes: 1

Views: 1088

Answers (3)

Jigneshk
Jigneshk

Reputation: 348

I have same requirement for my project. In my project I have to allow user to access some pages and some pages to admin. Mostly admin can access everything, but I have to block user to access some pages/Action. I did below thing.

a. Create one class to Authenticate user/admin.

b. Create one class for User and inherited that class from "ActionFilterAttribute", and override the OnActionExecuting method.

c. Create one class for Admin and did samething as mentioned in "b", but for admin.

d. put the Authentication class name above the class name or method depending on access.

see sample code(step b). I removed some code, but you can get the idea.

public class AuthenticateUser : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext context)
        {
            //Do session check.
            if (HttpContext.Current.Session["Id"] == null || String.IsNullOrEmpty(HttpContext.Current.Session["Id"].ToString()))
            {
                HttpContext.Current.Response.StatusCode = HttpStatusCode.Forbidden.GetHashCode();
                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    filterContext.Result = new JsonResult { Data = new { Status = HttpStatusCode.Forbidden, LogonRequired = true, result = "Session Expired" }, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
                }
                else
                {
                    //redirect to login page
                    UrlHelper oUrl = new UrlHelper(HttpContext.Current.Request.RequestContext);
                    string s = oUrl.Action("", "UserInfo/");
                    HttpContext.Current.Response.Redirect(s);
                }
            }

            //If usertype is User then allow it. If user type is admin then return redirect.

            //Redirect code if admin
            UrlHelper oUrl = new UrlHelper(HttpContext.Current.Request.RequestContext);
            string s = oUrl.Action("", "UserInfo/");
            HttpContext.Current.Response.Redirect(s);

        }
    }

Upvotes: 1

Fran
Fran

Reputation: 6530

Use claims. each public controller action claim that you need to define.

Then have your roles defined by the list of claims/operations they can do.

Here's a great explanation here Role-based access control (RBAC) vs. Claims-based access control (CBAC) in ASP.NET MVC

Upvotes: 0

LiranBo
LiranBo

Reputation: 2146

I would define it differently, just give each user a set of roles.

Define each user with more than one role, if someone has access to write, you set a role for him to write, if he can also read you can add another role - read.

Now when you define your actions you can use this format[Authorize(Roles = Role.Read)]. Set each action by the access right it requires and you are done.

Upvotes: 0

Related Questions