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 =new RedirectResult("/Home/Error");进行重定向
            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 以上就是全部代码



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

Over





原文地址:https://www.cnblogs.com/AnAng/p/8657447.html