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

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

时间: 2024-10-12 12:07:26

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

Asp.net Core, 基于 claims 实现权限验证 - 引导篇

什么是Claims? 这个直接阅读其他大神些的文章吧,解释得更好. 相关文章阅读: http://www.cnblogs.com/JustRun1983/p/4708176.html http://www.cnblogs.com/jesse2013/p/aspnet-identity-claims-based-authentication-and-owin.html http://www.cnblogs.com/savorboard/p/aspnetcore-identity.html clai

ASP.NET Core 打造一个简单的图书馆管理系统(五)初始化书籍信息

前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/?view=aspnetcore-2.1&tabs=windows <Pro ASP.NET MVC 5>.<锋利的 jQuery> 此系列皆使用 VS2017+C# 作为开发环境.如果有什么问题或者意见欢迎在留言区进行留言.

ASP.NET Core 打造一个简单的图书馆管理系统(九) 学生信息增删(终章)

前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/?view=aspnetcore-2.1&tabs=windows <Pro ASP.NET MVC 5>.<锋利的 jQuery> 当此系列文章写完后会在一周内推出修正版. 此系列皆使用 VS2017+C# 作为开发环境.如果

ASP.NET Core 打造一个简单的图书馆管理系统 (修正版)(七) 学生信息增删(伪终章)

前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/?view=aspnetcore-2.1&tabs=windows <Pro ASP.NET MVC 5>.<锋利的 jQuery> 此系列皆使用 VS2017+C# 作为开发环境.如果有什么问题或者意见欢迎在留言区进行留言.

ASP.NET Core 打造一个简单的图书馆管理系统(三)基本登录页面以及授权逻辑的建立

前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/?view=aspnetcore-2.1&tabs=windows <Pro ASP.NET MVC 5>.<Bootstrap 开发精解>.<锋利的 jQuery> 此系列皆使用 VS2017+C# 作为开发环境.

ASP.NET Core 打造一个简单的图书馆管理系统(四)密码修改以及密码重置

 前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/?view=aspnetcore-2.1&tabs=windows <Pro ASP.NET MVC 5>.<Bootstrap 开发精解>.<锋利的 jQuery> 此系列皆使用 VS2017+C# 作为开发环境

ASP.NET Core 打造一个简单的图书馆管理系统(七)外借/阅览图书信息的增删改查

前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/?view=aspnetcore-2.1&tabs=windows <Pro ASP.NET MVC 5>.<锋利的 jQuery> 此系列皆使用 VS2017+C# 作为开发环境.如果有什么问题或者意见欢迎在留言区进行留言.

ASP.NET Core 打造一个简单的图书馆管理系统(八)学生借阅/预约/查询书籍事务

前言: 本系列文章主要为我之前所学知识的一次微小的实践,以我学校图书馆管理系统为雏形所作. 本系列文章主要参考资料: 微软文档:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/?view=aspnetcore-2.1&tabs=windows <Pro ASP.NET MVC 5>.<锋利的 jQuery> 当此系列文章写完后会在一周内推出修正版. 此系列皆使用 VS2017+C# 作为开发环境.如果

[外包]!采用asp.net core 快速构建小型创业公司后台管理系统(三)

接着上一章节继续唠唠 本章主要说一下Redis Redis操作优化 一.基础类的配置工作 1.我想信许多人(许多neter人)操作redis依然用的是StackExchange.Redis,这个neget包,并没有用国内现在一些大佬们推出了包 RedisOptions主要是redis连接的一个配置类 实现代码如下: public class RedisOptions { /// <summary> /// 数据库地址 /// </summary> public string Red