ASP.NET如何制作后台权限管理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ASP.NET如何制作后台权限管理相关的知识,希望对你有一定的参考价值。

你是想自己写后管理系统,还是就为有一个后台权限呀? 如果是后台管理系统,你就按照登录那样做就可以,在里面可以再加限制访问页面 如果登录成功,则可以进入后台系统如果不登录或登录失败,都让它跳转到一个指定的页面,进行错误的报告,然后让登录的人从新登录 参考技术A 设置两张表一张作为菜单表:字段 类型MenuID int (自增)MenuUrl nvarchar(255)一张为权限表:字段 类型LimitID int(自增)MenuIDArray nvarchar(255) 然后在用户表上加个字段LimitID,保存的是权限表的LimitID字段(注:MenuIDArray保存的是Menu表上的MenuID值,格式可以为:“1,2,3,4,5,6”,中间以逗号隔开那种,或者以竖线隔开,然后,用Split将MenuIDArray转换为string[]数组类型,来显示该用户拥有的页面ID,其后,显示该用户拥有的页面)。以达到权限效果。

asp.net core 拦击器制作的权限管理系统DEMO

技术分享图片

效果图

没有登陆不会执行请求日期的方法,不管是否登陆都不允许访问请求时间方法

验证不通过是会进行转发到Home/error方法中,

唯一有点遗憾的是会进行两次请求,而不是一次。

代码附上:

    [Route("[controller]/[action]")]
    public class HomeController : BaseController
    {
        /// <summary>
        /// Ajax请求页面
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult AjaxView()
        {
            return View();
        }
        /// <summary>
        /// 登陆接口
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Login()
        {
            LoginMember();
            return Json("登陆成功");
        }
        /// <summary>
        /// 清除登陆信息
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult ClearLogin() {
            ClearMember();
            return Json("注销成功");
        }
        /// <summary>
        /// 登陆后也不能请求的接口
        /// </summary>
        /// <returns></returns>
        public IActionResult GetNoData()
        {
            return Json("时间是" + DateTime.Now.ToLongTimeString());
        }
        /// <summary>
        /// 请求数据接口
        /// </summary>
        /// <returns></returns>
        public IActionResult GetData() {
            return Json("今天是" + DateTime.Now.ToLongDateString());
        }
        /// <summary>
        /// 请求页面接口
        /// </summary>
        /// <returns></returns>
        public IActionResult GetDataView()
        {
            return View();
        }

        /// <summary>
        /// 请求不通过接口
        /// </summary>
        /// <returns></returns>
        public IActionResult Error()
        {
            return Json("你没有权限");
        }


    }

 

AjaxView视图页:
<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>AjaxView</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script type="text/javascript" >
        $(function () {
            $("#Login").click(function () { 
                $.get("/Home/Login", "", function (data) {
                    alert(data);
                })
            })
            $("#ClearLogin").click(function () {
                $.get("/Home/ClearLogin", "", function (data) {
                    alert(data);
                })
            })
            $("#Getdata").click(function () {
                $.get("/Home/GetData", "", function (data) {
                    alert(data);
                })
            })
            $("#GetTime").click(function () {
                $.get("/Home/GetNoData", "", function (data) {
                    alert(data);
                })
            })


        })
    </script>
</head>
<body>
    <button id="Login">登陆</button>
    <button id="ClearLogin">注销</button>
    <button id="Getdata">请求日期</button>
    <button id="GetTime">请求时间</button>
</body>
</html>
4个请求


支持类(用户类与权限类、枚举):
  /// <summary>
    /// 用户类
    /// </summary>
    public class Member {
        public string Name { get; set; }
        //允许请求的连接
        public IEnumerable<RightsManagement> RightsList { get; set; }
    }
    /// <summary>
    /// 权限类
    /// </summary>
    public class RightsManagement {
        public int ID { get; set; }
        /// <summary>
        /// 允许请求的路径
        /// </summary>
        public string AllowRequest { get; set; }
    }

    public enum ErrorEnum {
        /// <summary>
        /// 没有登陆
        /// </summary>
        NoLogin=1,
        /// <summary>
        /// 不允许访问
        /// </summary>
        NoAllow=2,
        /// <summary>
        /// 可以访问
        /// </summary>
        OK=3
    }

全局变量

  /// <summary>
        /// error 方法地址
        /// </summary>
        protected string ErrorAction { get; private set; } = "Error";
        /// <summary>
        /// error 方法地址
        /// </summary>
        protected string ErrorController { get; private set; } = "Home";
        /// <summary>
        /// 用户类 ,为了直观点就这样弄了
        /// </summary>
        protected static Member member { get; private set; }

        /// <summary>
        /// 所有人都能访问的接口,以下接口不会被拦截
        /// </summary>
        protected List<RightsManagement> RightsList { get; set; } = new List<RightsManagement>() {
              new RightsManagement(){
                        ID=3,
                        AllowRequest="Home/Login"
                    },
                       new RightsManagement(){
                        ID=4,
                        AllowRequest="Home/ClearLogin"
                    },
                        new RightsManagement(){
                        ID=5,
                        AllowRequest="Home/Error"
                    }
                        ,
                        new RightsManagement(){
                        ID=5,
                        AllowRequest="Home/AjaxView"
                    }
        };
        
        private ErrorEnum errorEnum;

 

登陆与注销函数
   /// <summary>
        /// 登陆函数
        /// </summary>
        public void LoginMember() {
            member = new Member()
            {
                Name = "张三",
                RightsList = new List<RightsManagement>() {
                    new RightsManagement(){
                        ID=1,
                        AllowRequest="Home/GetData"//接口
                    },
                     new RightsManagement(){
                        ID=2,
                        AllowRequest="Home/GetDataView"//视图页
                    }
                }
            };
        }
        /// <summary>
        /// 清除登陆信息
        /// </summary>
        public void ClearMember() {
            member = null;
        }

 

拦截器重写了父类的

OnActionExecutionAsync方法
如果不是asp.net core 将不会有这个方法
OnActionExecuting方法似乎无法决定控制器执行的方法,
   /// <summary>
        /// 请求开始前异步调用
        /// </summary>
        /// <param name="context">参数</param>
        /// <param name="next">一个已经封装好的委托</param>
        /// <returns></returns>
        public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            thecontext = context;
            //获取请求的路径 并进行拼接
            string theControllerAndAction = context.ActionDescriptor.RouteValues["controller"] + "/" + context.ActionDescriptor.RouteValues["action"];
            if (RightsList.Where(d=>d.AllowRequest== theControllerAndAction).Count()>0)
            {
                //允许默认允许的请求通过
                return base.OnActionExecutionAsync(context, next);
            }
            //定义一个委托 用于表示next下一步执行的方法
            ActionExecutionDelegate thenext = new ActionExecutionDelegate(TaskOnActionExecutionAsync);
            if (member == null)
            {
                //没有登陆
                errorEnum = ErrorEnum.NoLogin;
            }
            else {
                if (member.RightsList.Where(d => d.AllowRequest == theControllerAndAction).Count() == 0)
                {
                    //没有请求的权利
                    errorEnum = ErrorEnum.NoAllow;
                }
                else {
                    errorEnum = ErrorEnum.OK;
                    //用base方法的去处理验证通过的请求,
                    //因为我不知道转发请求的性能是否有额外开销
                    return base.OnActionExecutionAsync(context, next);
                }
            }
            return base.OnActionExecutionAsync(context, thenext);
        }

 

Task 方法

  Task<ActionExecutedContext> TaskOnActionExecutionAsync() {
            Task<ActionExecutedContext> thetask = new Task<ActionExecutedContext>(funcOnActionExecutionAsync, thecontext);
            thetask.Start();
            return thetask;
        }
//这是一个全局的临时变量,在控制器中 每次请求都会重置他
  ActionExecutingContext thecontext;
funcOnActionExecutionAsync方法
 ActionExecutedContext funcOnActionExecutionAsync(object o) {
            ActionExecutingContext theaction = o as ActionExecutingContext;
            ActionExecutedContext theactionExecutedContext = new ActionExecutedContext(theaction, theaction.Filters, theaction.Controller);
            //表示跳过控制器方法访问直接返回数据给浏览器,也就是不跳转不进入控制器方法但是有异常信息返回
            //theaction.Result = Json("请求成功");
            switch (errorEnum)
            {
                case ErrorEnum.NoLogin:
                    //使用一个比较捞的重定向,因为我怎么也改变不了他请求的控制器方法
                    theaction.Result = RedirectToAction(ErrorAction, ErrorController);
                    break;
                case ErrorEnum.NoAllow:
                    theaction.Result = RedirectToAction(ErrorAction, ErrorController);
                    break;
                case ErrorEnum.OK:
                    theaction.Result = RedirectToAction(theaction.ActionDescriptor.RouteValues["action"], theaction.ActionDescriptor.RouteValues["controller"]);
                    break;
                default:
                    break;
            }
            return theactionExecutedContext;
        }

 


OK 以上就是全部代码

以上代码有两个问题
1、无法在本次请求中选择要执行的控制器方法
虽然在 ActionExecutingContext.Controller有控制器实例并且可以直接调用,
控制器本身也是一个类
但是我就是感觉不是这样弄得。

2、保存用户信息的方法
其中可访问链接我是用list保存,也不知道有没有更好的方法。

Over





 






























以上是关于ASP.NET如何制作后台权限管理的主要内容,如果未能解决你的问题,请参考以下文章

Asp.Net Mvc通用后台管理系统,bootstrap+easyui+权限管理+ORM

asp.net core 拦击器制作的权限管理系统DEMO

ASP.NET权限如何设置?

ASP.NET-权限管理五张表

net core体系-web应用程序-4asp.net core2.0 项目实战-13基于OnActionExecuting全局过滤器,页面操作权限过滤控制到按钮级

谁知道ASP.NET网站后台管理怎莫做?