EFのcode fristの下で安定した権限管理システムを書く:MVCフィルタブロック、権限コア(5)

7801 ワード

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class PowerAttribute : FilterAttribute, IActionFilter
    {

        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            //throw new NotImplementedException();
        }
        /// <summary>
        ///  
        /// </summary>
        public string PowerName { get; set; }
        /// <summary>
        ///  
        /// </summary>
        public bool IsSuper = false;

        protected User LoginUser = null;

        protected PowerConfig Power = null;

        public IPowerConfigService powerConfigService = AutofacDependencyResolver.Current.ApplicationContainer.Resolve<IPowerConfigService>();
        
        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            LoginUser = CacheHelper.GetCache(Constant.CacheKey.LoginUserInfoCacheKey + "_" + filterContext.HttpContext.User.Identity.Name) as User;
            bool b = false;

            if (IsSuper == false)
            {
                // 

                // id 
                string[] acts = LoginUser.Role.ActionIds.Split(',');

                Power = CacheHelper.GetCache(Constant.CacheKey.PowerConfigCacheKey) as PowerConfig;

                if (Power == null)
                {
                    Power = powerConfigService.LoadConfig(Constant.PowerConfigPath);
                    CacheHelper.SetCache(Constant.CacheKey.PowerConfigCacheKey, Power);
                }


                try
                {
                    if (Power != null)
                    {
                        var p = Power.PowerList.FirstOrDefault(t => t.Name == PowerName);
                        if (p != null)
                        {
                            if (acts.Contains(p.Id.ToString()))
                            {
                                // 
                                b = true;
                            }
                        }
                    }
                }
                catch
                {
                    b = false;
                }
            }
            // 
            if (LoginUser.IsSuperUser)
            {
                b = true;
            }

            #region  
            if (b == false)
            { // 
                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {

                    //filterContext.Result = new JsonResult() {
                    //    Data = new { pass = false, error = " " },
                    //    JsonRequestBehavior=JsonRequestBehavior.AllowGet
                    //};

                    filterContext.Result = new ContentResult()
                    {
                        Content = " ",
                        ContentEncoding = Encoding.UTF8
                    };
                }
                else
                {
                    filterContext.Controller.ViewData["ErrorMessage"] = " ";//filterContext.Exception.Message + "  ! !";// 
                    filterContext.Result = new ViewResult()//new url Error 
                    {
                        ViewName = "Error",/* Shard */
                        ViewData = filterContext.Controller.ViewData//view viewdata 
                    };
                }
            }
            #endregion
        }
    }

このフィルタリングを使用して様々なactionのアクセスをブロックし、権限の粒子化を行い、使用時に直接actionまたはcontrollerのヘッダに[power(IssSuper=true,PowerName="権限名")]、Issperはシステムスーパー管理者向けに設計され、actionがシステムレベルのactionであるかどうかを判断し、一般的には構成または高権限のactionで使用され、一般的には書かないか、falseであることができる.
Powerのパラメータ構成は2つの場所に置いて、1つのデータベース、もう1つはconfigファイルで、データベースは私が設計したエクスポートを通じて、直接configになります.実行時にキャラクタのactionIdに基づいてプロファイルからID対応のpowernameを取り出し、powenameに基づいて判断する(powernameは重複可能であり、actionの細分化パケットに有利)
<?xml version="1.0"?>
<PowerConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <PowerGroupList>
    <PowerGroup>
      <GroupName> </GroupName>
      <Id>1</Id>
    </PowerGroup>
    <PowerGroup>
      <GroupName> </GroupName>
      <Id>2</Id>
    </PowerGroup>
  </PowerGroupList>
  <PowerList>
    <Power>
      <ParamStr>/cms/1234</ParamStr>
      <Name> </Name>
      <GroupId>1</GroupId>
      <Id>2</Id>
    </Power>
    <Power>
      <ParamStr>/cms/12345</ParamStr>
      <Name> </Name>
      <GroupId>1</GroupId>
      <Id>3</Id>
    </Power>
    <Power>
      <ParamStr>/links/123</ParamStr>
      <Name> </Name>
      <GroupId>1</GroupId>
      <Id>7</Id>
    </Power>
    <Power>
      <ParamStr>/cms/123</ParamStr>
      <Name> </Name>
      <GroupId>1</GroupId>
      <Id>8</Id>
    </Power>
    <Power>
      <ParamStr>/proj</ParamStr>
      <Name> </Name>
      <GroupId>1</GroupId>
      <Id>9</Id>
    </Power>
    <Power>
      <ParamStr>/message</ParamStr>
      <Name> </Name>
      <GroupId>1</GroupId>
      <Id>10</Id>
    </Power>
    <Power>
      <ParamStr>/gundong</ParamStr>
      <Name> </Name>
      <GroupId>1</GroupId>
      <Id>11</Id>
    </Power>
    <Power>
      <ParamStr>/guangao</ParamStr>
      <Name> </Name>
      <GroupId>1</GroupId>
      <Id>12</Id>
    </Power>
    <Power>
      <ParamStr>/cms/123</ParamStr>
      <Name> </Name>
      <GroupId>2</GroupId>
      <Id>1</Id>
    </Power>
    <Power>
      <ParamStr>/admin/ActionAdd</ParamStr>
      <Name> </Name>
      <GroupId>2</GroupId>
      <Id>4</Id>
    </Power>
    <Power>
      <ParamStr>/cms/12</ParamStr>
      <Name> </Name>
      <GroupId>2</GroupId>
      <Id>5</Id>
    </Power>
    <Power>
      <ParamStr>/cms/123</ParamStr>
      <Name> </Name>
      <GroupId>2</GroupId>
      <Id>6</Id>
    </Power>
  </PowerList>
</PowerConfig>

上に生成されたconfigがあり、実行時にキャッシュにロードされ、パフォーマンスが向上します.彼の生成は、ActionとActionGroupに基づいており、ActionとActionGroupのデータはデータベースに格納され、追加を可視化することができます.