效果图
没有登陆不会执行请求日期的方法,不管是否登陆都不允许访问请求时间方法
验证不通过是会进行转发到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 core 拦击器制作的权限管理系统DEMO
原文地址:https://www.cnblogs.com/AnAng/p/8657447.html