Heim  >  Artikel  >  Backend-Entwicklung  >  Grafikdetails der Asp.net-Kernprojekt-MVC-Berechtigungssteuerung mit zugewiesenen Berechtigungen

Grafikdetails der Asp.net-Kernprojekt-MVC-Berechtigungssteuerung mit zugewiesenen Berechtigungen

黄舟
黄舟Original
2017-03-06 11:05:182381Durchsuche

Der beste Weg zu lernen ist, es selbst zu tun. Hier werden wir ein gemeinsames Berechtigungsverwaltungssystem entwickeln, um Asp.net Core von Grund auf zu erleben und zu lernen. Der Gesamtplan des Projekts sieht ungefähr wie folgt aus:

Im vorherigen Artikel wurde erläutert, wie Berechtigungen gesteuert werden. Das heißt, beim Zugriff auf einen Controller oder eine Methode muss der aktuelle Benutzer über bestimmte Berechtigungen verfügen Programm? Im Folgenden finden Sie eine Einführung in die Verwendung des Microsoft.AspNetCore.Identity.EntityFrameworkCore-Frameworks zum Zuweisen von Berechtigungen.

Bevor wir die Zuweisungsmethode einführen, müssen wir die Berechtigungsbeziehung verstehen, die drei Objekte umfasst: Benutzer, Rollen und Berechtigungen werden Rollen zugewiesen, und Rollen werden Benutzern zugewiesen Nach dem Hinzufügen der Rolle verfügt der Benutzer über die Liste der in der Rolle enthaltenen Berechtigungen. Beispielsweise gibt es jetzt eine Informationsadministratorrolle, die Berechtigungen zum Löschen von Informationen enthält. Wenn der Benutzer Zhang San die Rolle des Informationsadministrators hat, hat Zhang San diese die Berechtigung zum Löschen von Informationen. In einigen speziellen Szenarien können Berechtigungen auch direkt Benutzern zugewiesen werden, was bedeutet, dass bestimmte Berechtigungen unter Umgehung von Rollen direkt Benutzern zugewiesen werden können. Eine solche Unterstützung wird im Microsoft.AspNetCore.Identity.EntityFrameworkCore-Framework bereitgestellt.

Stellen Sie zunächst die wichtigsten Geschäftsobjektklassen im Framework vor:

IdentityUser: Stellt eine Benutzerinformation dar

IdentityRole: Stellt eine Rolleninformation dar

IdentityRoleClaimfd2b5144600653aa5f8a48596a998260: Zeigt die Berechtigungen des Benutzers an

IdentityUserRole7c013bef549e108856916cfbe0707d60: Zeigt die Benutzerrollenbeziehung an


Nachdem wir die Grundkonzepte verstanden haben, werfen wir einen Blick darauf, wie Berechtigungen zugewiesen werden.

1. Weisen Sie Rollen Berechtigungen zu: Microsoft.AspNetCore.Identity.EntityFrameworkCore stellt die RoleManager-Klasse bereit, die Methoden zum Zuweisen von Berechtigungen zu Rollen bereitstellt:

Task9b1f9e47eb1620cf27a98765de10fb89 Claim)

 Der erste Parameter stellt das entsprechende Rollenobjekt dar und der zweite Parameter stellt eine Berechtigungsinformation dar

2. Weisen Sie Benutzern Berechtigungen zu: Microsoft.AspNetCore.Identity.EntityFrameworkCore Die UserManager-Klasse wird bereitgestellt in der Klasse, die Methoden zum Zuweisen von Berechtigungen an Benutzer bereitstellt:

Task9b1f9e47eb1620cf27a98765de10fb89 eine Berechtigungsinformation

3, Benutzer Rollen zuweisen: Die UserManager-Klasse wird ebenfalls verwendet, die verwendete Methode:

 AddToRoleAsync(TUser user, string role)

Der erste Parameter stellt das Benutzerobjekt dar und der zweite Parameter ist der Name der Rolle

4 Rufen Sie die Liste der Berechtigungen ab, die die Rolle derzeit besitzt:

Taskfebce605adaafd9dd572348f5a5bf2a8 GetClaimsAsync(TRole-Rolle)

5, rufen Sie die Liste der Berechtigungen ab, über die der Benutzer derzeit verfügt:

Taskfebce605adaafd9dd572348f5a5bf2a8> UserManager.GetClaimsAsync(TUser-Benutzer)

Auf diese Weise kann der gesamte Prozess der Berechtigungszuweisung abgeschlossen werden. In Kombination mit der vorherigen Berechtigungssteuerungsmethode kann das System die vollständige Berechtigungssteuerungslogik realisieren.

Die Frage ist nun, woher kommt die Berechtigungsliste? Im Allgemeinen wird nach der Bestimmung einer Geschäftssystemfunktion natürlich auch die entsprechende Berechtigungsliste bestimmt. Beim Zuweisen von Berechtigungen zu Rollen und zum Zuweisen von Berechtigungen zu Benutzern müssen Sie lediglich alle Berechtigungen auf der Seite zur Auswahl auflisten folgt:

Rufen Sie einfach die entsprechende Methode auf, um die ausgewählten Daten zu speichern.

Dieses Problem ist gelöst, aber es entsteht ein neues Problem. Wenn eine Geschäftsfunktion zu viele Punkte hat, führt dies natürlich zu vielen Berechtigungen. Wenn sie vollständig manuell auf die Seite geschrieben wird, ist der Arbeitsaufwand natürlich sehr groß. Darüber hinaus kann sich das Geschäftssystem weiterhin ändern Ich werde auch die Seite zur Berechtigungszuweisung ständig ändern. Dies ist natürlich keine gute Methode, die meiner Meinung nach nicht die beste ist, aber sie kann viel Ärger ersparen.

Das Problem, das wir für die erste Show lösen müssen, besteht darin, wie wir diese Berechtigungskonfigurationsliste schnell erstellen können.

Die Idee besteht darin, das AuthorizeAttribute umzuwandeln, Berechtigungsbeschreibungsinformationen basierend auf dieser Funktion hinzuzufügen und die Berechtigungsbeschreibungsinformationen als Richtlinie zu verwenden. Gehen wir direkt zum 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;
        }
      }
    }
  }

Die Klasse wurde definiert, also sehen wir uns an, wie man sie verwendet. Da es sich um eine Feature-Definition handelt kann im Controller verwendet werden. Verwenden Sie die folgende Struktur für Klassen oder Methoden:

[Resource("Organisationsstruktur", Aktion = "Abteilung hinzufügen")]

Die grundlegende Arbeit wurde hier abgeschlossen , und es müssen noch zwei weitere Probleme gelöst werden:

1 Die Richtlinie ist jetzt nur mit einem Namen konfiguriert, aber die spezifischen Verifizierungsregeln sind nicht definiert

2 alle Berechtigungslisten

先来看第一个问题,前面的文章介绍了,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[] { &#39;-&#39; }, 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.Transientd35cc227e13486608ede2963927abb51());

再来看第二个问题,我们已经在控制器或者方法上定义了权限信息,关键是我们如何从这些特性里获取到权限列表,将来用于权限分配的时候使用。在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)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn