前段时间公司要求做一个外来人员扫描身份证进入公司 要求内部人员可以预约外来访问 ,就要求做一个权限系统。 这里是配合前端做的一个代码 笔记一下 以防mybase又文件损坏
1.权限过滤器部分
/// <summary> /// 权限验证过滤器 /// </summary> [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class AuthAttribute : AuthorizeAttribute { #region 属性 /// <summary> /// 区域名称 /// </summary> private string AreaName { get; set; } /// <summary> /// 当前控制器名称 /// </summary> private string ControllerName { get; set; } /// <summary> /// 当前行为名称 /// </summary> private string ActionName { get; set; } /// <summary> /// 行为类型 /// </summary> private Framework.ActionType ActionType { get; set; } /// <summary> /// 是否允许匿名访问 /// </summary> private bool AllowAnonymous { get; set; } /// <summary> /// 是否登录后即可访问 /// </summary> private bool AllowLogined { get; set; } #region 最终结果 /// <summary> /// 无权使用 /// </summary> private bool Limited { get; set; } /// <summary> /// 未登录 /// </summary> private bool UnLogin { get; set; } /// <summary> /// 登录超时 /// </summary> private bool LoginTimeout { get; set; } #endregion #endregion /// <summary> /// 在过程请求授权时调用 /// 自带的AllowAnonymous特性依旧会执行本方法,但会略过AuthorizeCore方法的执行。 /// </summary> /// <param name="filterContext">筛选器上下文</param> public override void OnAuthorization(AuthorizationContext filterContext) { var AD = filterContext.ActionDescriptor; var CD = AD.ControllerDescriptor; this.AreaName = (filterContext.RouteData.DataTokens["area"] == null ? "" : filterContext.RouteData.DataTokens["area"]).ToString().ToLower(); this.ControllerName = CD.ControllerName; this.ActionName = AD.ActionName; this.AllowAnonymous = false; this.Limited = false; this.LoginTimeout = false; this.UnLogin = false; this.AllowAnonymous = AD.GetCustomAttributes(typeof(AllowAnonymousAttribute), false).Length > 0 || CD.GetCustomAttributes(typeof(AllowAnonymousAttribute), false).Length > 0; this.AllowLogined = false;//AD.GetCustomAttributes(typeof(AllowLoginedAttribute), false).Length > 0 || CD.GetCustomAttributes(typeof(AllowLoginedAttribute), false).Length > 0; var tempActionTypes = AD.GetCustomAttributes(typeof(CatchExceptionAttribute), false); if (tempActionTypes.Length > 0) { var tempActionType = (tempActionTypes[0] as CatchExceptionAttribute); this.ActionType = tempActionType.Type.HasValue ? tempActionType.Type.Value : SF.Framework.ActionType.View; } else { this.ActionType = Framework.ActionType.View; } base.OnAuthorization(filterContext); } /// <summary> /// 授权判定核心 /// </summary> /// <param name="httpContext">筛选器上下文</param> /// <returns></returns> protected override bool AuthorizeCore(HttpContextBase httpContext) { if (this.AllowAnonymous) { return base.AuthorizeCore(httpContext); } else { //bool logined = httpContext.User.Identity.IsAuthenticated; bool logined = Authentication.isLogin(); //string currentUserName = httpContext.User.Identity.Name; string currentUserName = Authentication.getUserName(); if (currentUserName.Equals(SF.Framework.SystemEnvironment.SuperAdminAccountName, StringComparison.CurrentCultureIgnoreCase)) { return true; } if (logined) { if (!this.AllowLogined) { //委托方法进行权限确认 SF.Framework.BLL.Security.Permission permission = new Framework.BLL.Security.Permission(); //委托方法 //permission.OnCheckAuth = CheckPower.Check; //获取权限判定结果 bool auth = permission.CheckAuth(currentUserName, this.AreaName, this.ControllerName, this.ActionName); if (!auth) { this.Limited = true; } } } else { if (string.IsNullOrWhiteSpace(currentUserName)) { this.UnLogin = true; } else { this.LoginTimeout = true; } } } return (this.Limited || this.UnLogin || this.LoginTimeout) ? false : base.AuthorizeCore(httpContext); //不知道为什么这里还要调用一次基类的 } /// <summary> /// 处理未能授权的 HTTP 请求 /// </summary> /// <param name="filterContext">筛选器上下文</param> protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { #region 无权访问 if (this.Limited) { string message = HttpUtility.HtmlEncode(CustomStatusCode.无权访问.ToString() + "指定路径:/" + this.ControllerName + "/" + this.ActionName); if (this.ActionType == Framework.ActionType.View) { filterContext.Result = new RedirectResult("/Blank/ShowMessagePage?message=" + message); } else { filterContext.Result = new HttpStatusCodeResult((int)CustomStatusCode.无权访问, message); filterContext.HttpContext.Response.Write(message); } } #endregion #region 未登录 if (this.UnLogin) { if (this.ActionType == Framework.ActionType.View) { filterContext.Result = new RedirectResult("/Blank/NotLoginPage?message=" + CustomStatusCode.未登录.ToString()); } else { string message = HttpUtility.HtmlEncode(CustomStatusCode.未登录.ToString()); filterContext.Result = new HttpStatusCodeResult((int)CustomStatusCode.未登录, message); filterContext.HttpContext.Response.Write(message); } } #endregion #region 登录超时 if (this.LoginTimeout) { if (this.ActionType == Framework.ActionType.View) { filterContext.Result = new RedirectResult("/Blank/NotLoginPage?message=" + CustomStatusCode.登录超时.ToString()); } else { string message = HttpUtility.HtmlEncode(CustomStatusCode.登录超时.ToString()); filterContext.Result = new HttpStatusCodeResult((int)CustomStatusCode.登录超时, CustomStatusCode.登录超时.ToString()); filterContext.HttpContext.Response.Write(message); } } #endregion } }
2.js部分 通过ajaxsetup来处理auth返回的异常信息
$.ajaxSetup({ statusCode: { 318: function (result) { $.messager.show({ title: 'Error', msg: result.responseText }); }, 319: function (result) { $.messager.show({ title: 'Error', msg: result.responseText }); }, 320: function (result) { $.messager.show({ title: 'Error', msg: result.responseText }); }, } });
处理流程大致是 为每个action添加特殊标记
[AuthAttribute] //权限 [CatchException(Framework.ActionType.Operation)] //异常
Auth 会根据异常过滤器的枚举ActionType来判断action的类型 并根据类型返回result
最后js会根据返回的结果来进行响应
这次的知识点大概在于 OnAuthorization获取被访问的action信息 及获取catchexception过滤器的部分