<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [認證 & 授權] 6. Permission Based Access Control

      在前面5篇博客中介紹了OAuth2和OIDC(OpenId Connect),其作用是授權和認證。那么當我們得到OAuth2的Access Token或者OIDC的Id Token之后,我們的資源服務如何來驗證這些token是否有權限來執行對資源的某一項操作呢?比如我有一個API,/books,它具有如下5個操作:

      POST /books 添加一本書
      GET /books/{id} 獲取一本書
      PUT /books/{id} 更新一本書
      DELETE /books/{id} 刪除一本書
      GET /books   獲取書的列表

      其偽代碼如下:

      [Route("books")]
      public class BooksController : Controller
      {
          [HttpGet("")]
          public Book[] Get() { return null; }
      
          [HttpGet("{bookId}")]
          public Book Get(int bookId) { return null; }
      
          [HttpPost("")]
          public Book Post(Book book) { return null; }
      
          [HttpPut("{bookId}")]
          public Book Put(int bookId, Book book) { return null; }
      
          [HttpDelete("{bookId}")]
          public Book Delete(int bookId) { return null; }
      }

      那么我們先看看基于OAuth2的Access Token,OIDC的Id Token和傳統的基于角色的權限控制是如何處理控制這些資源的操作。

      1 OAuth2的Access Token之Scope

      我們都知道OAuth2的最終產物是提供給我們一個Access Token,而這個Access Token中包含了一個Scope的字段,這個字段代表的是授權服務器或者資源擁有者授予第三方客戶端允許操作資源服務器的哪些資源的范圍。這里有一點需要注意的是,這個授權過程可以有資源擁有著的參與(Authorization Code,Implicit,Resource Owner Password Credentials Grant),也可以沒有他的參與(Client Credentials Grant)。那么基于上述的books的資源,我們可以定義一個 book_manager 的Scope,來控制對books的五個操作的權限控制。那么Books的基于Scope的權限控制看起來就像是這樣的:

      [Route("books")]
      public class BooksController : Controller
      {
          [HttpGet("")]
          [Scope("book_manager")]
          public Book[] Get() { return null; }
      
          [HttpGet("{bookId}")]
          [Scope("book_manager")]
          public Book Get(int bookId) { return null; }
      
          [HttpPost("")]
          [Scope("book_manager")]
          public Book Post(Book book) { return null; }
      
          [HttpPut("{bookId}")]
          [Scope("book_manager")]
          public Book Put(int bookId, Book book) { return null; }
      
          [HttpDelete("{bookId}")]
          [Scope("book_manager")]
          public Book Delete(int bookId) { return null; }
      }

      注意看紅色的部分,為每一個操作都添加了一個Scope的描述。如果Access Token擁有book_manager這個Scope(不管他是OAuth2的哪一個授權方式頒發的,我們的最終代碼部分只認Scope),那么對這些API的調用就是被允許的,否則視為無權操作。

      2 OIDC的Id Token之sub

      關于Id Token的用途以及其包含哪些信息請參考Id Token。Id Token和Access Token的不同之處在于它一定是包含某一個用戶的標識 sub ,但是沒有Scope,這是因為Id Token的用途是認證當前用戶是誰,所以用戶是必須存在的;由于僅僅是認證,則不會包含被認證用戶可以做哪些操作之類的授權相關的事情。那么針對Id Token,我們的API應該如何進行權限管控呢?通常的做法是使用傳統的基于校色的權限控制(Role Based Access Control)。其實現細節就不解釋了,它的模型大致是:一個實體(用戶或者組織)擁有一組角色,每一個角色代表著一組權限集合。感覺是不是和Scope很像呢,其實差不多。我們定義一個這樣的角色 圖書管理員 吧。這里是故意和Scope的命名區分開的,因為其來源不同,那么我們最終實現的時候也會是獨立開來的。

       1 [Route("books")]
       2 public class BooksController : Controller
       3 {
       4     [HttpGet("")]
       5     [Scope("book_manager")]
       6     [Role("圖書管理員")]
       7     public Book[] Get() { return null; }
       8 
       9     [HttpGet("{bookId}")]
      10     [Scope("book_manager")]
      11     [Role("圖書管理員")]
      12     public Book Get(int bookId) { return null; }
      13 
      14     [HttpPost("")]
      15     [Scope("book_manager")]
      16     [Role("圖書管理員")]
      17     public Book Post(Book book) { return null; }
      18 
      19     [HttpPut("{bookId}")]
      20     [Scope("book_manager")]
      21     [Role("圖書管理員")]
      22     public Book Put(int bookId, Book book) { return null; }
      23 
      24     [HttpDelete("{bookId}")]
      25     [Scope("book_manager")]
      26     [Role("圖書管理員")]
      27     public Book Delete(int bookId) { return null; }
      28 }

      如果 sub 代表的用戶自身擁有或者其所屬的組織機構擁有(不管其是怎么組織管理的吧,最終我們可以知道這個用戶是否具有某一個角色) 圖書管理員 這個角色。則允許其訪問books的這些操作。

      3 以上兩種方式的弊端在哪里?

      其實不止以上兩種,比如在Asp.Net Core中有內置的這些授權控制組件:

      1 [Authorize(Policy = "AtLeast21")]
      2 public class AlcoholPurchaseController : Controller
      3 {
      4     public IActionResult Login() => View();
      5 
      6     public IActionResult Logout() => View();
      7 }

      以上這些本質上和上面的基于Scope和基于Role的屬于同一種類型。我們這樣做當然可以工作,但是問題來了,它們直觀嗎,靈活嗎?繁瑣嗎?好用嗎?能滿足我們變化的需求嗎?總有著一種把簡單的事情搞復雜的感覺。比如現在我增需要增加一個角色,超級管理員,那么上述的代碼是不是需要我們做出改變呢?

      1 [HttpGet("")]
      2 [Scope("book_manager")]
      3 [Role("圖書管理員","超級管理員")]
      4 public Book[] Get() { return null; }

      再比如,現在需要增加一個Scope book_reader ,它只能執行讀取的操作,又要做出改變了吧。況且即使我們把Scope和Role合二為一了,還是混亂不堪。

      4 基于權限為最小粒度的解決方案

      那么造成這些問題的根本原因是什么?答:不管是Scope還是Role它們體現的都是一個隱式的描述信息,而不是某一個具體的操作行為的描述信息。既然我們知道了其癥結所在,那么怎么解決這個問題呢?原理很簡單,使用權限作為我們的最小單元,把Scope和Role等等還有其他的一些管理組織權限的概念都作為一個中間層,禁止它們出現在接口權限驗證的地方,而是僅作為管理組織Permission的手段存在。然后改造上面的代碼如下:

       1 [Route("books")]
       2 public class BooksController : Controller
       3 {
       4     [HttpGet("")]
       5     [Permission("books.read")]
       6     public Book[] Get() { return null; }
       7 
       8     [HttpGet("{bookId}")]
       9     [Permission("book.read")]
      10     public Book Get(int bookId) { return null; }
      11 
      12     [HttpPost("")]
      13     [Permission("book.add")]
      14     public Book Post(Book book) { return null; }
      15 
      16     [HttpPut("{bookId}")]
      17     [Permission("book.edit")]
      18     public Book Put(int bookId, Book book) { return null; }
      19 
      20     [HttpDelete("{bookId}")]
      21     [Permission("book.delete")]
      22     public Book Delete(int bookId) { return null; }
      23 }

      我們把每一個操作都定義一個權限Permission,不管你是Access Token的Scope,還是Role,都不會在這里出現。比如在檢查超級管理員是不是能操作的時候,我們可以直接放行(把這些檢查和我們對接口的操作權限的描述分開)。如果是名為book_reader的Scope的時候,我們讓book_reader只關聯books.readbook.read這兩個Permission,而這種關聯關系的管理,我們是可以通過數據存儲來維持的,也很方便的提供管理頁面來靈活的配置。而最終的代碼上關心的只是Permission這種方式可以稱為Resource Based Access Control或者Permission Based Access Control

      5 Apache Shiro

      以上是我自己的一些理解和思路,然后我發現了Apache Shiro這個項目,感覺就像是找到了組織,Apache Shiro走的更遠,而且為Permission定義了一套規則。強烈建議讀一讀https://shiro.apache.org/permissions.html這篇文檔。而.Net這邊就沒有這么好的福氣了,,,Asp.Net Core中的默認授權過濾器還是傳統的方式。

       

      不過基于Asp.Net Core的Filter:IAuthorizationFilter,我們可以把這一整套授權控制方式給替換掉:使用代碼:https://github.com/linianhui/oidc.example/tree/master/src/web.oauth2.resources;Filters代碼:https://github.com/linianhui/oidc.example/tree/master/src/aspnetcore.filters.permissions

      從此和討厭的 [Authorize(Roles ="圖書管理員",Policy ="XXX")] 說再見。

      以上只是個人的一些理解,如有錯誤,歡迎指正。

      參考

      https://shiro.apache.org/

      強烈推薦:https://shiro.apache.org/permissions.html

      https://stormpath.com/blog/new-rbac-resource-based-access-control

      https://docs.microsoft.com/en-us/aspnet/core/security/authorization/

      posted @ 2018-01-13 15:23  Timetombs  閱讀(6429)  評論(20)    收藏  舉報
      主站蜘蛛池模板: 99久久激情国产精品| 菠萝菠萝蜜午夜视频在线播放观看| 欧美激情肉欲高潮视频| 男女xx00xx的视频免费观看| 午夜福利在线观看入口| 白丝乳交内射一二三区| 亚洲午夜精品久久久久久抢| 国产一级三级三级在线视 | 90后极品粉嫩小泬20p | 久久天天躁综合夜夜黑人鲁色| 国产精品毛片一区视频播| 日韩永久永久永久黄色大片| 蜜芽久久人人超碰爱香蕉| 乱人伦中文字幕成人网站在线| 国内少妇偷人精品免费| 红桃视频成人传媒| 少妇熟女天堂网av| 日韩国产中文字幕精品| 吕梁市| 国产精品毛片av999999| 国产香蕉尹人在线视频你懂的| 玩弄丰满少妇人妻视频| 婷婷综合缴情亚洲| 性色在线视频精品| 国产最新AV在线播放不卡| 国产精品国产自产拍高清| 一区二区三区人妻无码| 亚洲精品综合久中文字幕| 91中文字幕一区在线| 鹤壁市| 国产一区二区三区不卡视频| 国产精品美女自慰喷水| 中文国产不卡一区二区| 国产精品一区二区三区四区| 亚洲中文字幕无码爆乳| 亚洲国产综合精品2020| 国产一区二区三区av在线无码观看| 国产午夜三级一区二区三| 国产亚洲精品综合一区二区| 国产精品美女自慰喷水| 国产中文字幕在线一区|