ASP.NET MVC Implementation of the Role Right -based permissions control system

2023-01-19   ES  

1: Introduction

We all know that ASP.NET MVC permissions control is the onrationulation method that implements AuthorizeAttribute class.

Below is the most common implementation method:

 public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
    
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
    
           if (!filterContext.RequestContext.HttpContext.Request.IsAuthenticated)
            {
    
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
     controller = "account", action = "login", returnUrl = filterContext.HttpContext.Request.Url, returnMessage = "You have no right to view." }));
                return;
            }
          base.OnAuthorization(filterContext);
        }
}

and then hit the [CustomautHorize] tag on the ACTION you need to verify.

This method is a relatively thick -grained solution. Since the definition (agreed) permissions Hard Code belt on the corresponding Action, it is impossible to achieve user custom permissions control.

Look at the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace Deepleo.Role.Controllers
{
    
    public class UserController : Controller
    {
    
        [UserAuthorize]
        public ActionResult Index()
        {
    
            return View();
        }
       [AdminAuthorize]
        public ActionResult Admin()
        {
    
            return View();
        }
        [UserAuthorize]
        public ActionResult Detail()
        {
    
            return View();
        }
    }
}

We have a UserController. He has 3 ACTION: Index, admin, depational. Among them, admin requires the system administrator permissions, and the other two values require user permissions. In this way, you need to establish AdminautHorizeAttribute and UserautHorizeAttribute. You cannot realize user -defined permissions in doing so.

2. Role -based permissions control system

RBAC (Role Based Access Control) is the most popular and most common permissions control system at present.
在这里插入图片描述
For ASP.NET MVC, this system is easy to implement: Each Action under Controller can be regarded as a permissions, and the role is equivalent to multiple permissions combinations.

Then we create a new ROLEAUUU andRizeAttribute, that is, the attribute description of the character.

2.1 How to learn power

The key to

This ROLEAUTHORIZEATTRIBUTE is how to get ControllerName and ActionName. It is actually easy to realize MSDN.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.Mvc;
using System.Web.Routing;
using Deepleo.Role.Services;

namespace Deepleo.Role.Attributes
{
    
    public class RoleAuthorizeAttribute : AuthorizeAttribute
    {
    
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
    
            var isAuth = false;
            if (!filterContext.RequestContext.HttpContext.Request.IsAuthenticated)
            {
    
                isAuth = false;
            }
            else
            {
    
                if (filterContext.RequestContext.HttpContext.User.Identity != null)
                {
    
                    var roleService = new RoleService();
                    var actionDescriptor = filterContext.ActionDescriptor;
                    var controllerDescriptor = actionDescriptor.ControllerDescriptor;
                    var controller = controllerDescriptor.ControllerName;
                    var action = actionDescriptor.ActionName;
                    var ticket = (filterContext.RequestContext.HttpContext.User.Identity as FormsIdentity).Ticket;
                    var role = roleService.GetById(ticket.Version);
                    if (role != null)
                    {
    
                        isAuth = role.Permissions.Any(x => x.Permission.Controller.ToLower() == controller.ToLower() && x.Permission.Action.ToLower() == action.ToLower());
                    }
                }
            }
            if (!isAuth)
            {
    
                filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new {
     controller = "account", action = "login", returnUrl = filterContext.HttpContext.Request.Url, returnMessage = "You have no right to view." }));
                return;
            }
            else
            {
    
                base.OnAuthorization(filterContext);
            }
        }
    }
}

Note: Here is a ticket Version to store Roleid. You can also use other ways.

mainly uses FilterContext.ActionDescriptor and FilterContext.actionDescriptor.

2.2 How to generate permissions control list

The collection of ROLE.Permissions in the previous

is already a good list of permissions.

The definition of

Permissions class is as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Deepleo.Role.Entities
{
    
    public class PermissionDefinition
    {
    
        public virtual int Id
        {
    
            set;
            get;
        }
        public virtual int ActionNo
        {
    
            set;
            get;
        }

        public virtual int ControllerNo
        {
    
            set;
            get;
        }
        public virtual string Name
        {
    
            set;
            get;
        }

        public virtual string ControllerName
        {
    
            set;
            get;
        }
        public virtual string Controller
        {
    
            set;
            get;
        }
        public virtual string Action
        {
    
            set;
            get;
        }
        public virtual DateTime AddDate
        {
    
            set;
            get;
        }
    }
}

Properties Controller and Action records permissions. ControllerName and ActionName are used to display UI, Controllerno and ActionNo to display sequential control.

Here you can manually enter all ACTION into the database, and then implement Rolservice. But obviously this method is too stupid. In fact, we can use reflex+Attribute mechanism to achieve automated load permissions control table. The principle is very simple, I will go directly to the key code.

The following is the code of reflection:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Deepleo.Role.Services;
using Deepleo.Role.Attributes;
using Deepleo.Role.Entities;

namespace Deepleo.Role.Controllers
{
    
    public class InstallController : Controller
    {
    
        public ActionResult Index()
        {
    
            return View();
        }

        [HttpPost]
        public ActionResult Index()
        {
    
            try
            {
    
                var roleService = new RoleService();
                #region init permission
                createPermission(new UserController());
                #endregion

                var allDefinedPermissions = roleService.GetDefinedPermissions();
                #regionSuper administrator role initialization
                var adminPermissions = new List<RolePermissionInfo>();
                foreach (var d in allDefinedPermissions)
                {
    
                    adminPermissions.Add(new RolePermissionInfo {
     AddDate = DateTime.Now, Permission = d, });
                }
                int adminRoleId = roleService.AddRole(new Entities.RoleInfo
                {
    
                    AddDate = DateTime.Now,
                    Description = "",
                    Name = "Super Administrator",
                    Permissions = adminPermissions
                });
                #endregion
                return RedirectToAction("Admin", "User");
            }
            catch (Exception ex)
            {
    
                ModelState.AddModelError("", ex.Message);
                return View();
            }
        }
        private void createPermission(Controller customController)
        {
    
            var roleService = new RoleService();

            var controllerName = "";
            var controller = ""; var controllerNo = 0;
            var actionName = ""; var action = ""; var actionNo = 0;
            var controllerDesc = new KeyValuePair<string, int>();

            var controllerType = customController.GetType();
            controller = controllerType.Name.Replace("Controller", "");//remobe controller posfix
            controllerDesc = getdesc(controllerType);
            if (!string.IsNullOrEmpty(controllerDesc.Key))
            {
    
                controllerName = controllerDesc.Key;
                controllerNo = controllerDesc.Value;
                foreach (var m in controllerType.GetMethods())
                {
    
                    var mDesc = getPropertyDesc(m);
                    if (string.IsNullOrEmpty(mDesc.Key)) continue;
                    action = m.Name;
                    actionName = mDesc.Key;
                    actionNo = mDesc.Value;
                    roleService.CreatePermissions(actionNo, controllerNo, actionName, controllerName, controller, action);
                }
            }
        }
        private KeyValuePair<string, int> getdesc(Type type)
        {
    
            var descriptionAttribute = (DescriptionAttribute)(type.GetCustomAttributes(false).FirstOrDefault(x => x is DescriptionAttribute));
            if (descriptionAttribute == null) return new KeyValuePair<string, int>();
            return new KeyValuePair<string, int>(descriptionAttribute.Name, descriptionAttribute.No);
        }
        private KeyValuePair<string, int> getPropertyDesc(System.Reflection.MethodInfo type)
        {
    
            var descriptionAttribute = (DescriptionAttribute)(type.GetCustomAttributes(false).FirstOrDefault(x => x is DescriptionAttribute));
            if (descriptionAttribute == null) return new KeyValuePair<string, int>();
            return new KeyValuePair<string, int>(descriptionAttribute.Name, descriptionAttribute.No);
        }
    }
}

The following is the code of Descriptingattribute:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Deepleo.Role.Attributes
{
    
    public class DescriptionAttribute : Attribute
    {
    
        public string Name
        {
    
            set;
            get;
        }
        public int No
        {
    
            set;
            get;
        }
    }
}

and then hit the Descriptingattribute label on the userController, just shown below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Deepleo.Role.Attributes;

namespace Deepleo.Role.Controllers
{
    
    [Description(No = 1, Name = "User")]
    public class UserController : Controller
    {
    
        [RoleAuthorize]
        [Description(No = 1, Name = "User Homepage")]
        public ActionResult Index()
        {
    
            return View();
        }
        [RoleAuthorize]
        [Description(No = 1, Name = "User Management")]
        public ActionResult Admin()
        {
    
            return View();
        }
        [RoleAuthorize]
        [Description(No = 1, Name = "User Details")]
        public ActionResult Detail()
        {
    
            return View();
        }
    }
}

Sample can be fully automated to create permissions when installing Install when installing the website.

This can accurately control the user -defined authority control of each Action.

Look at my labor results:

在这里插入图片描述
Write at the end: The division of HTTPGET and HTTPPOST of the same name is divided into two permissions. For example: New [httpget], and New [httppost]. It is mainly that this does not make much sense. Of course, if your business needs must be the case, I think it should be easy to expand.

Full code download: http://files.cnblogs.com/deepleo/rolesolution.rar

PS: The code only has a key code and does not implement the ROLESERVICE method. Please implement it according to your actual situation.

source

Random Posts

5. Overview and instructions of Dockerfile What is

ASP.NET MVC from the controller to pass data to the four ways of view (1)

CodeForcess Round # 636 (div. 3) (part)

spark aggregate function detailed explanation

Hibernate’s SaveorUpdate Public Method