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のデータはデータベースに格納され、追加を可視化することができます.