Search code examples
asp.netasp.net-mvcauthorizationasp.net-identityprivileges

How to set a privilege inside a role in ASP.NET MVC?


I currently have a system where there is a user table, a role table, and a user-roles association table, where one user can be associated to multiple roles (like Admin, BasicUser, etc.). I am able to authorize action methods based on these roles. This is from the Identity framework.

Now I want to add support for privileges so that action methods can be restricted based on those as well, rather than just by roles. For example, in a Controller, I may have an HTTPPost action that only someone with a "Write" privilege should be able to perform successfully.

What changes do I need to make so that I can assign privileges to roles? I.E., I want to select the "Admin" role to have the "Write" and "Read" privileges, while a "BasicUser" role will only be assigned a "Read" privilege. This way, an Admin can access any method that is allowed by the Write privilege, while the BasicUser can not.

If I were to create another table called "Privilege" and an association table between that and roles, and the code to set privileges in a role, how can I use the privilege as a filter? So for example, the below action should only be allowed to be performed by a user in a role that has the "Write" privilege attributed to it.

[Write]
public ActionResult Create()
{
   return View();
}

Thank you.


Solution

  • The same way the AuthorizeAttribute works, you can create a custom authorization attribute inheriting from it:

    public class AuthorizePrivilegeAttribute : AuthorizeAttribute
    {
        // Custom property
        public string Privilege { get; set; }
    
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            // Reusing default authentication. 
            var isAuthorized = base.AuthorizeCore(httpContext);
            if (!isAuthorized)
            {                
                return false;
            }
    
            return YourCustomCode.HasPrivilege(this.Privilege))      
        }
    }
    

    Then using it on top of your method:

    [AuthorizePrivilege(Privilege = "Write")]
    public ActionResult Create()
    {
        return View();
    }