前面的文章引见了怎样举行权限掌握,即接见掌握器或许要领的时刻,请求当前用户必需具有特定的权限,然则如安在顺序中举行权限的分派呢?下面就引见下怎样应用Microsoft.AspNetCore.Identity.EntityFrameworkCore框架举行权限分派。
在引见分派要领之前,我们必需明白权限关联,这内里涉及到三个对象:用户,角色,权限,权限分派到角色,角色再分派到用户,当某个用户属于某个角色后,这个用户就具有了角色所包括的权限列表,比方如今有一个信息治理员角色,这个角色包括了信息删除权限,当张三这个用户具有信息治理员角色后,张三就具有了信息删除的权限。在某些特殊场景下,权限也能够直接分派到用户,也就是说能够直接把某些特定的权限,绕过角色,直接分派给用户。Microsoft.AspNetCore.Identity.EntityFrameworkCore框架中都供应了如许的支撑。
先把框架中重要的营业对象类引见一下:
IdentityUser:示意一个用户信息
IdentityRole:示意一个角色信息
IdentityRoleClaim<TKey>:示意角色具有的权限
IdentityUserClaim<TKey>:示意用户具有的权限
IdentityUserRole<TKey>:示意用户角色关联
基本概念明白后,下面我们就来看一下怎样举行权限分派。
1,分派权限到角色:Microsoft.AspNetCore.Identity.EntityFrameworkCore中供应了RoleManager类,类中供应了把权限分派到角色的要领:
Task<IdentityResult> AddClaimAsync(TRole role, Claim claim)
第一个参数示意对应的角色对象,第二个参数示意一个权限信息
2,分派权限到用户:Microsoft.AspNetCore.Identity.EntityFrameworkCore中供应了UserManager类,类中供应了把权限分派到用户的要领:
Task<IdentityResult> AddClaimAsync(TUser user, Claim claim)
第一个参数示意对应的用户对象,第二个参数示意一个权限信息
3,分派用户到角色:用到的同样是UserManager类,运用的要领:
AddToRoleAsync(TUser user, string role)
第一个参数示意的是用户对象,第二个是角色的称号
4,猎取角色当前具有的权限列表:
Task<IList<Claim>> RoleManager.GetClaimsAsync(TRole role)
5,猎取用户当前具有的权限列表:
Task<IList<Claim>> UserManager.GetClaimsAsync(TUser user)
经由过程如许的体式格局就能够完成权限分派全过程,再连系前面的权限掌握要领,体系就完成了完成的权限掌握逻辑。
那如今的题目来了,权限列表从什么处所来?一般来说,一个营业体系功用肯定后,对应的权限列表也天然就肯定了,再完成分派权限到角色,分派权限到用户的功用时,只须要在页面上把一切的权限列出来举行挑选即可,效果图以下:
把挑选的数据挪用对应的要领保留即可。
这个题目处理了,然则新的题目又来了。假如说一个营业功用点迥殊多,天然会致使权限也会许多,假如完整经由过程手工的体式格局写到页面上,那天然事情量会很大很大,再者营业体系可能会不断地变化,这个时刻也会去不断地修正权限分派页面,这天然不是一个好的要领,下面我给人人说一个我想的一个要领,不一定是最好的,然则能省很大的事。
首秀我们须要处理的题目是,怎样疾速生成这个权限设置列表。
思绪就是革新AuthorizeAttribute,在这个特征基本上增添权限形貌信息,用权限形貌信息作为Policy。下面直接上代码:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited =true)] //类称号能够改,由于我把体系操纵看成资本来治理 public class ResourceAttribute:AuthorizeAttribute { private string _resouceName; private string _action; public ResourceAttribute(string name) { if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException(nameof(name)); } _resouceName = name; //把资本称号设置成Policy称号 Policy = _resouceName; } public string GetResource() { return _resouceName; } public string Action { get { return _action; } set { _action = value; if (!string.IsNullOrEmpty(value)) { //把资本称号跟操纵称号组装成Policy Policy = _resouceName + "-" + value; } } } }
类已定义好了,那我们就看看怎样运用,由于是特征定义,所以能够在掌握器类或许要领上依据下面构造运用:
[Resource("构造架构", Action = "增加部门")]
到这里基本事情已做完,下面另有两个题目须要处理:
1,Policy如今只是设置了称号,然则详细考证划定规矩没有定义
2,怎样猎取一切的权限列表
先来看第一个题目,前面的文章引见了,Policy须要提早在startup里经由过程AddAuthorization举行设置,然则如今我们并没有做如许的步骤,所以现在权限还不会起作用。框架在权限考证的时刻,会依靠一个IAuthorizationPolicyProvider来依据Policy称号猎取详细的划定规矩,天然我们会想到自定义一个IAuthorizationPolicyProvider完成,代码以下:
public class ResourceAuthorizationPolicyProvider : IAuthorizationPolicyProvider { private AuthorizationOptions _options; public ResourceAuthorizationPolicyProvider(IOptions<authorizationoptions> options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } _options = options.Value; } public Task<authorizationpolicy> GetDefaultPolicyAsync() { return Task.FromResult(_options.DefaultPolicy); } public Task<authorizationpolicy> GetPolicyAsync(string policyName) { AuthorizationPolicy policy = _options.GetPolicy(policyName); //由于我们policy的称号实在就是对应的权限称号,所以能够用以下逻辑返回须要的考证划定规矩 if (policy == null) { string[] resourceValues = policyName.Split(new char[] { '-' }, StringSplitOptions.None); if (resourceValues.Length == 1) { _options.AddPolicy(policyName, builder => { builder.AddRequirements(new ClaimsAuthorizationRequirement(resourceValues[0], null)); }); } else { _options.AddPolicy(policyName, builder => { builder.AddRequirements(new ClaimsAuthorizationRequirement(resourceValues[0], new string[] { resourceValues[1] })); }); } } return Task.FromResult(_options.GetPolicy(policyName)); } } </authorizationpolicy></authorizationpolicy></authorizationoptions>
完成了IAuthorizationPolicyProvider,我们就须要在startup.cs的ConfigureServices(IServiceCollection services)要领中举行注册,操纵以下:
复制代码 代码以下:
services.TryAdd(ServiceDescriptor.Transient<IAuthorizationPolicyProvider, ResourceAuthorizationPolicyProvider>());
再来看第二个题目,我们已在掌握器或许要领上定义了权限信息,关键是我们怎样从这些特征里猎取到权限列表,未来用于权限分派的时刻运用。在asp.net core mvc中供应了一个类剖析机制,IApplicationModelProvider,这个依靠信息比较多,这里就不过量引见,后续我会零丁开一个系列,引见asp.net core mvc的内部机制。
直接上代码
public class ResourceApplicationModelProvider : IApplicationModelProvider { private readonly IAuthorizationPolicyProvider _policyProvider; public ResourceApplicationModelProvider(IAuthorizationPolicyProvider policyProvider) { _policyProvider = policyProvider; } public void OnProvidersExecuted(ApplicationModelProviderContext context) { } public void OnProvidersExecuting(ApplicationModelProviderContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } List<resourceattribute> attributeData = new List<resourceattribute>(); //轮回猎取一切的掌握器 foreach (var controllerModel in context.Result.Controllers) { //获得ResourceAttribute var resourceData = controllerModel.Attributes.OfType<resourceattribute>().ToArray(); if (resourceData.Length > 0) { attributeData.AddRange(resourceData); } //轮回掌握器要领 foreach (var actionModel in controllerModel.Actions) { //获得要领的ResourceAttribute var actionResourceData = actionModel.Attributes.OfType<resourceattribute>().ToArray(); if (actionResourceData.Length > 0) { attributeData.AddRange(actionResourceData); } } } //把一切的resourceattribute的信息写到一个全局的resourcedata中,resourcedata就能够在其他处所举行运用,resourcedata定义背面补充 foreach (var item in attributeData) { ResourceData.AddResource(item.GetResource(), item.Action); } } public int Order { get { return -1000 + 11; } } } </resourceattribute></resourceattribute></resourceattribute></resourceattribute>
resourcedata定义以下
public class ResourceData { static ResourceData() { Resources = new Dictionary<string, List<string>>(); } public static void AddResource(string name) { AddResource(name, ""); } public static void AddResource(string name,string action) { if (string.IsNullOrEmpty(name)) { return; } if (!Resources.ContainsKey(name)) { Resources.Add(name, new List<string>()); } if (!string.IsNullOrEmpty(action) && !Resources[name].Contains(action)) { Resources[name].Add(action); } } public static Dictionary<string, List<string>> Resources { get; set; } }
然后在startup中注册我们方才定义的IApplicationModelProvider:
复制代码 代码以下:
services.TryAddEnumerable(ServiceDescriptor.Transient<IApplicationModelProvider, ResourceApplicationModelProvider>());
然后在权限分派页面经由过程ResourceData.Resources就猎取到了一切的权限信息,然后经由过程轮回的体式格局直接显现到页面上即可。
终究写完了,哈哈~~
以上就是asp.net core项目mvc权限掌握 分派权限的图文概况的内容,更多相关内容请关注ki4网(www.ki4.cn)!