user2537609
user2537609

Reputation: 23

ASP.NET MVC Role based Privileges for Controller Actions

I have a ASP.NET MVC4 web application with tables users, roles and rolePrivileges

userid username password roleid] values: 1 user1 12345 3, 2 user2 12345 1, 3 user3 12345 2

[roleid, rolename ] values: 1 admin, 2 client, 3 guest, 4 ...

[Roleid, Action, GrantAccess] values: 1 /Home/Index Y 1 /Home/Settings Y 1 /Home/Dashboard Y 2 /Home/Index Y 2 /Home/Settings N 2 /Home/Dashboard Y 3 /Home/Index Y 3 /Home/Settings N 3 /Home/Dashboard N

I would like to achieve the following in ASP.NET MVC forms authentication:

A controller action should be dynamically granted denied access to a role , and if a user tries to access a controller action which the user is not granted access the application should signout.

1) I want to know the best way to achieve this since hardcoding the rolename like Authorize(Roles="admin")] will not work

2) I also have user specific settings which would need to be initialized on user log in ,in asp.net forms this was stored in session variables can the same be done using TempData in asp.net MVC is this is best practice?

Upvotes: 2

Views: 4147

Answers (1)

nerdybeardo
nerdybeardo

Reputation: 4675

You could create an action filter based on a role group instead of a role. The role group could be stored in your database in a 1 to many relationship. (i.e. 1 group has many roles). Then feed the group name to the action filter.

public class RoleGroupFilterAttribute : ActionFilterAttribute
{
    public string GroupName { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string [] users = new string[] {};
        string [] roles = new string[] {};

        // get the roles / users for the group from your db or storage
        // below is an example only
        roles = mydb.RoleGroups.Where(r=>r.Name == GroupName).Select(r=>r.Roles).ToArray();

        var user = filterContext.HttpContext.User;
        var userRoles = Roles.GetRolesForUser();

        if (!roles.Any(r => userRoles.Contains(r)) && !users.Contains(user.Identity.Name))
        {
            // return a not found result or redirect to an action
            filterContext.Result = new HttpNotFoundResult();
        }
    }
}

To use you can simply create administration pages to manage your role groups. And adding the filter to your controller or action is very easy.

[RoleGroupFilter(GroupName="MyGroup")]
public ActionResult Index()
{
    return View();
}

In the example above I also allowed adding users to the role group but that would be your choice.

Upvotes: 3

Related Questions