Asp.net-mvc – Dynamically assign controller action permissions to roles in asp.net MVC

asp.netasp.net-identity-2asp.net-mvc

I am working on asp.net mvc 5. I want to assign permissions of controllers' action methods to roles dynamically without hard conding the roles in Authorize attribute.

Here is the scenario –
In my project, I have four roles – Student, Teacher, Program Officer and Admin.
I want that admin can change the accessability of each role whenever he wishes. I do not want to hard code the authorize attribute with role names before every action name of controller because admin will not then be able to change the permissions of each role.

I want to create a page where every action method of controller will be listed as checkbox and admin can select action checkboxes for a role. Then that role users will get accessability of those action methods.

Here I want to make the UI as following –

Role Management UI

Can anyone please help me to do this by giving any suggestion or code or link?

Best Answer

Imagine you have service which returns array of roles based on controller and action name like this:

public class RoleProvider
{
    public string[] Get(string controller, string action)
    {
        // get your roles based on the controller and the action name 
        // wherever you want such as db
        // I hardcoded for the sake of simplicity 
        return new string[]{"Student", "Teacher"};
    }
}

Now you can write your own authorization attribute something like this:

public class DynamicRoleAuthorizeAttribute: AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        var controller = httpContext.Request.RequestContext
            .RouteData.GetRequiredString("controller");
        var action = httpContext.Request.RequestContext
            .RouteData.GetRequiredString("action");
        // feed the roles here
        Roles = string.Join("," ,_rolesProvider.Get(controller, action));
        return base.AuthorizeCore(httpContext);
    }
}

Now use your custom authorization attribute instead of older one like this:

[DynamicRoleAuthorize]
public ActionResult MyAction()
{

}