NFine一个隐藏的漏洞(NFine基本上模仿力软的,力软应该也有,不知道新版本改了没),就是任何登录的用户都可以进行权限修改操作。
比如所有模块的SumbitForm或者其它弹出窗口上的按钮,本身只有登录权限验证,只要是登录用户就可以直接通过模拟Post,Get请求直接进行修改操作。

为了解决这个问题,本文实现一个权限管理办法,防止直接绕过验证,以ItemsData为例,下面上代码。

[HttpPost]
        [HandlerAjaxOnly]
        [HandlerAuthorize(true, @"/SystemManage/ItemsData/Form")]
        [ValidateAntiForgeryToken]
        public ActionResult SubmitForm(ItemsDetailEntity itemsDetailEntity, string keyValue)
        {
            itemsDetailApp.SubmitForm(itemsDetailEntity, keyValue);
            return Success("操作成功。");

注意HandlerAuthorize与原有的有什么不同,可能有人会问,为什么要使用/SystemManage/ItemsData/Form,因为这个模块的修改按钮权限就是这个,为了保持一致性。

public bool Ignore { get; set; }
        public string AuthorizeAction { get; set; }
        public HandlerAuthorizeAttribute(bool ignore = true,string authorizeAction="")
        {
            Ignore = ignore;
            AuthorizeAction = authorizeAction;
        }

  原有的moduleId使用的cookie,根本就是防君子不防小人,而且影响判断,所以去掉。

private bool ActionAuthorize(ActionExecutingContext filterContext)
        {
            var operatorProvider = OperatorProvider.Provider.GetCurrent();
            var roleId = operatorProvider.RoleId;
            var moduleId = "";
            var action = HttpContext.Current.Request.ServerVariables["SCRIPT_NAME"].ToString();
            if (!string.IsNullOrEmpty( AuthorizeAction))//指定需要某Action权限
            {
                action = AuthorizeAction;
            }
            return new RoleAuthorizeApp().ActionValidate(roleId, moduleId, action);
        }
 
public bool ActionValidate(string roleId, string moduleId, string action)
        {

            ....

           else
            {
                authorizeurldata = cachedata;
            }
            //authorizeurldata = authorizeurldata.FindAll(t => t.F_Id.Equals(moduleId));
            foreach (var item in authorizeurldata)
            {
                if (!string.IsNullOrEmpty(item.F_UrlAddress))
                {
                    string[] url = item.F_UrlAddress.Split('?');
                    //if (item.F_Id == moduleId && url[0] == action)
                    if (url[0] == action)
                    {
                        return true;
                    }
                }
            }
            return false;