国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - asp.net core項目mvc權限控制:分配權限

asp.net core項目mvc權限控制:分配權限

2021-12-24 13:28dxp_909 ASP.NET教程

學習的最好方法就是動手去做,這里以開發一個普通的權限管理系統的方式來從零體驗和學習Asp.net Core。項目的整體規劃大致如下

前面的文章介紹了如何進行權限控制,即訪問控制器或者方法的時候,要求當前用戶必須具備特定的權限,但是如何在程序中進行權限的分配呢?下面就介紹下如何利用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)

通過這樣的方式就可以完成權限分配全過程,再結合前面的權限控制方法,系統就實現了完成的權限控制邏輯。

那現在的問題來了,權限列表從什么地方來?一般來說,一個業務系統功能確定后,對應的權限列表也自然就確定了,再實現分配權限到角色,分配權限到用戶的功能時,只需要在頁面上把所有的權限列出來進行選擇即可,效果圖如下:asp.net core項目mvc權限控制:分配權限

把選擇的數據調用對應的方法保存即可。

這個問題解決了,但是新的問題又來了。如果說一個業務功能點特別多,自然會導致權限也會很多,如果完全通過手工的方式寫到頁面上,那自然工作量會很大很大,再者業務系統可能會不斷地變化,這個時候也會去不斷地修改權限分配頁面,這自然不是一個好的方法,下面我給大家說一個我想的一個方法,不一定是最好的,但是能省很大的事。

首秀我們需要解決的問題是,如何快速生成這個權限配置列表。

思路就是改造authorizeattribute,在這個特性基礎上增加權限描述信息,用權限描述信息作為policy。下面直接上代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[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實現,代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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的內部機制。

直接上代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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定義如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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就獲取到了所有的權限信息,然后通過循環的方式直接顯示到頁面上即可。 

終于寫完了,哈哈~~

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 日本欧美在线 | 一区二区三区在线观看国产 | 1区2区视频| 久久精品无码一区二区日韩av | 天堂在线免费视频 | 免费a级毛片大学生免费观看 | 校园春色av | 精品国产乱码一区二区三区 | 日日骚视频 | 国产精品国产三级国产aⅴ原创 | 欧美中文字幕在线 | 欧美视频在线观看免费 | 狠狠色狠色综合曰曰 | 99精品一区二区三区 | 久久久久9999国产精品 | 日韩一区二区三区电影在线观看 | 午夜免费视频 | 四季久久免费一区二区三区四区 | 日韩中文字幕一区二区高清99 | 91精品国产综合久久精品 | 黄色在线免费 | 欧美激情高清 | 噜噜噜噜噜色 | 日本一区二区三区四区 | 国产精品久久久久免费a∨ 狠狠影院 | 亚洲免费在线视频 | bxbx成人精品一区二区三区 | 欧美一区二区三区精品 | 高清av一区 | 精品一区二区三区在线观看 | 亚洲午夜精品 | 黄色国产 | 日韩精品在线播放 | 国产色视频一区 | 日本理伦片午夜理伦片 | 播放毛片 | 欧美伦理一区二区三区 | 国产福利在线观看 | 久久福利 | 极品粉嫩饱满一线天在线 | 欧美亚洲 |