.NET MVC 通过过滤器处理权限问题 配合前端

前段时间公司要求做一个外来人员扫描身份证进入公司 要求内部人员可以预约外来访问 ,就要求做一个权限系统。 这里是配合前端做的一个代码 笔记一下 以防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过滤器的部分

猜你喜欢

转载自www.cnblogs.com/star-craft/p/8855580.html