.NetCore中若是實現權限控制的問題,當咱們訪問到一個Action操做的時候,咱們須要進行權限控制緩存
基於角色控制總以爲範圍有點過大,並且控制起來感受也不是太好,舉一個例子就是,一個添加操做Action,若是經過角色控制,經過寫起來就有點痛苦async
若是一個添加操做有20個角色均可以訪問,那麼在角色上須要指定好全部的角色,經過用戶中的角色Claims匹配訪問ui
經過Claims中的編碼
claims.Add(new Claim(ClaimTypes.Role, "rolecode"));
[Authorize(Roles ="rolecode")]
固然也能夠經過自定實現 接口,下面功能點相似的方式,經過角色服務獲取判斷,這裏須要處理的就是獲取 角色屬性上的角色名稱 ActionDescriptor 、 IAuthorizeData 獲取 Role的值spa
if (!context.HttpContext.User.IsInRole("rolename")) { context.Result = new ForbidResult(); }
固然也能夠經過策略處理,策略就是一個大雜燴,提供了不一樣的配置方案以下面給出的例子code
[Authorize(Policy ="policyname")]
services.AddAuthorization(options => { options.AddPolicy("policyname", policy => { policy.RequireRole("rolename1", "rolename2"); policy.RequireClaim("claimname"); policy.RequireUserName("username"); } ); });
上面的方式感受不是太好,有的時候咱們須要動態的配置功能點權限blog
好比,在系統中添加了一個角色,這個角色也擁有管理其中的一個Action權限,這裏就須要去設置action上的Role規則,若是使用基於角色Claim控制就顯得很很差了接口
若是採用策略方式的話都須要去修改代碼,並且還須要對系統很熟悉,那些地方使用了那些策略或者角色,這樣也不行,因此咱們採用下面的Claims功能點控制ip
這裏咱們須要去建立一個屬性(Attribute)標籤,且實現 IAsyncAuthorizationFilter 接口ci
若是功能點很少,數據量比較小的狀況下,能夠把功能點信息直接添加到 claims中,若是過多 只能動態獲取,或者動態讀取緩存提升效率
下面看下實現代碼
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] public class AuthorizeCodeAttribute : Attribute, IAsyncAuthorizationFilter { public AuthorizeCodeAttribute(string name) { Name = name; } public string Name { get; set; } public async Task OnAuthorizationAsync(AuthorizationFilterContext context) { if (!context.HttpContext.User.HasClaim(c => c.Value == Name)) { context.Result = new ForbidResult(); } await Task.CompletedTask; } }
接下來就是在Action上指定好相關的功能點編碼就好了
[AuthorizeCode(PermissionsConfig.ClassAdd)] public IActionResult Create() { return View(); }
若是Claims信息過多能夠經過獲取服務動態查詢獲得後進行驗證 或者 緩存服務(Redis、Cache)獲得,在Startup中DI上你的服務便可
var services= context.HttpContext.RequestServices.GetService<T>();
對於Claims信息的處理能夠在登陸 SignIn 的時候寫入相關的Claims身份信息便可,這裏須要提到的是 ClaimsIdentity(身份信息)、ClaimsPrincipal(身份人,當事人,身份全部人)