【实战 Ids4】║ 认证中心之内部加权
本期配套視頻:
https://www.bilibili.com/video/BV1sJ41197af?p=9
(昔我往矣,楊柳依依,今我來思,雨雪霏霏)
1、為什么需要在認證內部加權
我們知道,認證中心的作用就是用來保護我們的資源服務器,所以說認證中心是一個保護者,當然,他在保護其他客戶端的時候,也需要對自己進行保護,舉例來說:
我的Ids4項目中,有用戶角色信息管理,客戶端數(shù)據(jù)管理等等,這些不可能讓普通的登錄用來來訪問的
因此我們同樣需要在認證中心內部實現(xiàn)加權處理,用來保護某些頁面或者說某些數(shù)據(jù)的安全性不被惡意攻擊或訪問。
當然除了不讓普通用戶訪問,我們也同樣為了區(qū)分公司內部管理員的身份和權限,也同樣需要如此,超級管理員有很高的權限,可以處理任意數(shù)據(jù)。
這就是為什么我們需要在認證中心內部進行權限管理的原因。
2、常見的加權方式有哪幾種
這個問題不僅僅是在認證中心,其實在任何的項目中,包括資源服務器中,我們也是常用這幾種權限處理方式,多數(shù)是基于角色控制的RBAC模式:
這幾種我都使用過,也都是各有利弊的,我在資源服務器Blog.Core中,用的是第④種,而這次在認證中心Blog.IdentityServer中,使用的是第③種。
第四種是最復雜的,保存到數(shù)據(jù)庫,可以實現(xiàn)動態(tài)的策略授權,我們通過配置數(shù)據(jù)庫,就可以針對任意一個頁面或者API進行控制,但是在認證中心中,有些過于復雜了,故暫時不用。
第一種是無狀態(tài)的,任意登錄的用戶都能訪問,起不到控制的作用,僅僅是起到防止那些訪客任意訪問的作用,故舍棄。
第二種其實和第三種是一樣的代碼,我舉例來說明:
從代碼中,我們可以看到,我雖然創(chuàng)建了一個簡單的策略,但是邏輯卻是獲取rolename角色名,判斷各自的角色,那我為啥不直接用第二種呢:
這樣豈不是更簡單,也不用寫處理器等邏輯了,直接這么寫一下即可。
下邊我會講為什么沒有用這個。
3、你的資源服務器是如何加權的
你可能會好奇,今天說的是認證中心的加權,為啥又說到了資源服務器?是不是多此一舉了,并不是,其實我們寫的每一行代碼都應該考慮下,是否對其他的有影響,是否對其他的項目有關聯(lián),今天說的認證中心也是,我先給大家回憶一下Blog.Core的資源服務器是如何權限控制的。
Blog.Core中,用到的是上面說的第四種,復雜數(shù)據(jù)庫的策略授權,我們把數(shù)據(jù)都配置到了數(shù)據(jù)庫中,通過角色+菜單+接口的三方約束,來實現(xiàn)當前用戶是否有權利訪問當前接口。
細心的你可能發(fā)現(xiàn)了,這個多對多的關系表中,我們用到的是RoleId,那這個Id是從哪里來的,肯定是從Ids4認證中心來的,畢竟用戶是在那里統(tǒng)一登錄注冊。
那是如何傳遞過來的,肯定是Token,進一步說明,是Token中的Cliams聲明,那我們繼續(xù)往前推,這個聲明是從哪里配置的?是這里:
這里用SeedData來舉例,生成種子數(shù)據(jù)的時候,我們把角色Id賦給了JwtClaimTypes.Role的Cliams節(jié)點,這個是一個常量,也就等于是role這個節(jié)點。
這樣的話,我們Token中的聲明中的role節(jié)點,其實就是我們的角色Id,那上邊反推的邏輯就成功了,我們再來總結下:
用戶登錄——>獲取token——>攜帶roleid——>資源服務器HttpContext解析token
——>得到roleid——>根據(jù)roleid獲取到指定的菜單mid和接口pid集合——>在策略授權中做邏輯判斷。
看似一切很合理,但是卻有一個問題,因為我Blog.Core是先開發(fā)的,所以假設我們的這個資源服務器代碼不改的話,認證中心就有了一點兒小問題。
4、認證中心的抉擇
當前我們的角色信息是用的id,那認證中心就不能使用第二種方案了:
因為這個時候,我們claims聲明中,獲取到的不是name,所以一定會失敗,就算當前用戶的角色真的是AdminTest,還是會失敗:
這是因為按照這種方案,它只認識role這個節(jié)點,但是這個節(jié)點是id,沒辦法,我們只能這么寫了:
雖然是通過了,但是看著還是感覺很不舒服,有點兒Bad Smell的意思。
所以這也就是我文章開頭說的,我為啥要新建了一個策略,使用rolename節(jié)點作為策略的原因了:
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,ClaimRequirement requirement){var claim = context.User.Claims.FirstOrDefault(c => c.Type == requirement.ClaimName);if (claim != null && claim.Value.Contains(requirement.ClaimValue)){context.Succeed(requirement);}return Task.CompletedTask;}5、總結
今天雖然講的是認證中心的加權處理,但是我們也要考慮到資源服務器的業(yè)務邏輯,
最終我還是采用的是:
資源服務器用roleid來配合菜單和接口id,實現(xiàn)權限分配;
認證中心采用策略方案,通過rolename來對頁面進行權限控制;
到此結束,Ids4實戰(zhàn)也告一段落了,很有意思也很能鍛煉人思維邏輯的一個框架,建議大家好好學習,不可中途放棄,加油。
總結
以上是生活随笔為你收集整理的【实战 Ids4】║ 认证中心之内部加权的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Docker-Compose搭建高可
- 下一篇: CDN加速小水管动态应用技巧