La meilleure façon d'apprendre est de le faire vous-même. Ici, nous développerons un système commun de gestion des autorisations pour expérimenter et apprendre Asp.net Core à partir de zéro. Le plan global du projet est à peu près le suivant
L'article précédent a présenté comment contrôler les autorisations, c'est-à-dire que lors de l'accès à un contrôleur ou à une méthode, l'utilisateur actuel doit disposer d'autorisations spécifiques, mais comment allouer des autorisations dans le programme ? Ce qui suit est une introduction à la façon d’utiliser le framework Microsoft.AspNetCore.Identity.EntityFrameworkCore pour attribuer des autorisations.
Avant d'introduire la méthode d'allocation, nous devons comprendre la relation d'autorisation, qui implique trois objets : les utilisateurs, les rôles et les autorisations sont attribués aux rôles, et les rôles sont attribués aux utilisateurs lorsqu'un utilisateur appartient à un. Après avoir ajouté le rôle, l'utilisateur disposera de la liste des autorisations incluses dans le rôle. Par exemple, il existe désormais un rôle d'administrateur d'informations, qui inclut les autorisations de suppression d'informations. Lorsque l'utilisateur Zhang San a le rôle d'administrateur d'informations, Zhang San l'aura. l’autorisation de suppression d’informations. Dans certains scénarios spéciaux, les autorisations peuvent également être attribuées directement aux utilisateurs, ce qui signifie que certaines autorisations peuvent être attribuées directement aux utilisateurs, en contournant les rôles. Une telle prise en charge est fournie dans le framework Microsoft.AspNetCore.Identity.EntityFrameworkCore.
Introduisez d'abord les principales classes d'objets métier dans le framework :
IdentityUser : représente une information utilisateur
IdentityRole : représente une information de rôle
IdentityRoleClaim< ;: Indique les autorisations du rôle
IdentityUserClaim
IdentityUserRole
Après avoir compris les concepts de base, voyons comment attribuer des autorisations.
1. Attribuer des autorisations aux rôles : Microsoft.AspNetCore.Identity.EntityFrameworkCore fournit la classe RoleManager, qui fournit des méthodes pour attribuer des autorisations aux rôles :
Task
Le premier paramètre représente l'objet de rôle correspondant et le deuxième paramètre représente une information d'autorisation
2 Attribuez des autorisations aux utilisateurs : Microsoft.AspNetCore.Identity.EntityFrameworkCore La classe UserManager est fournie. dans la classe, qui fournit des méthodes pour attribuer des autorisations aux utilisateurs :
Task
Le premier paramètre représente l'objet utilisateur correspondant, le deuxième paramètre représente une information d'autorisation
3, attribuer des rôles aux utilisateurs : la classe UserManager est également utilisée, la méthode utilisée :
AddToRoleAsync(TUser user, string role)
Le premier paramètre représente l'objet utilisateur, et le deuxième paramètre est le nom du rôle
4. Obtenez la liste des autorisations actuellement détenues par le rôle :
Task
5, obtenez la liste des autorisations dont l'utilisateur dispose actuellement :
Task
De cette manière, l'ensemble du processus d'attribution des autorisations peut être complété. En combinaison avec la méthode de contrôle des autorisations précédente, le système peut réaliser la logique complète de contrôle des autorisations.
Maintenant, la question est : d'où vient la liste des autorisations ? De manière générale, une fois qu'une fonction du système d'entreprise est déterminée, la liste d'autorisations correspondante est naturellement déterminée. Lors de l'attribution d'autorisations aux rôles et de l'attribution d'autorisations aux utilisateurs, il vous suffit de répertorier toutes les autorisations sur la page de sélection. Oui, le rendu est le même. suit :
Appelez simplement la méthode correspondante pour enregistrer les données sélectionnées.
Ce problème est résolu, mais un nouveau problème surgit. Si une fonction métier comporte trop de points, elle entraînera naturellement beaucoup d'autorisations. Si elle est écrite entièrement manuellement sur la page, la charge de travail sera naturellement très importante. De plus, le système métier peut continuer à changer. , je modifierai également constamment la page d'attribution des autorisations. Ce n'est naturellement pas une bonne méthode. Maintenant, je vais vous expliquer une méthode à laquelle je pense. Ce n'est peut-être pas la meilleure, mais cela peut éviter bien des problèmes.
Le problème que nous devons résoudre pour la première émission est de savoir comment générer rapidement cette liste de configuration des autorisations.
L'idée est de transformer AuthorizeAttribute, d'ajouter des informations de description d'autorisation basées sur cette fonctionnalité et d'utiliser les informations de description d'autorisation comme stratégie. Passons directement au code :
[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; } } } }
La classe a été définie, voyons donc comment l'utiliser. Parce que c'est une définition de fonctionnalité, elle. peut être utilisé dans le contrôleur Utiliser la structure suivante sur les classes ou les méthodes :
[Resource("Organizational Structure", Action = "Add Department")]
Le travail de base a été terminé ici , et il y en a deux autres ci-dessous. Les problèmes doivent être résolus :
1. La politique n'est configurée qu'avec un nom, mais les règles de vérification spécifiques ne sont pas définies
2. listes
先来看第一个问题,前面的文章介绍了,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
再来看第二个问题,我们已经在控制器或者方法上定义了权限信息,关键是我们如何从这些特性里获取到权限列表,将来用于权限分配的时候使用。在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权限控制 分配权限的图文详情的内容,更多相关内容请关注PHP中文网(www.php.cn)!