哈嘍你們好,很久都沒有寫文章了,此次又從新開始寫技術文章了,半年前我仍是一直保持每週都寫文章的,後來是爲了響應羣友的號召,開始踏上了錄製視頻(https://www.bilibili.com/video/av58096866),直播授課(https://live.bilibili.com/21507364)的道路,目前看來效果還算基本及格吧,雖然人氣沒有那些大佬的多,不過我也是一直很盡心力,包括字幕的錄入,每週三按期的講課,不過真的很累,可是自認爲作的還能夠了,只是沒能申請上MVP,今年惟一的遺憾🙃。html
編者按:git
不少小夥伴說,學不懂受權認證,搞不懂 IdentityServer4 ,看不懂文章啥意思。固然具體怎麼採用仍是看所在公司的技術能力上限,可是從我的將來知識規劃出發,這些知識點仍是須要考慮的,有益無害。github
爲何忽然想要寫文章了呢,我是有強迫症的,目前開源了五個系列的文章,從 NetCore 到 Vue,從 Admin 到 Nuxt,而後從 DDD 到 IdentityServer4,我自認爲都是貼近實戰的,由於看到某些小夥伴說,應用到了公司的項目裏,我也是很開心,並且 NetCore 項目的Github start 數也破千了,我感謝每個點贊評論的小夥伴,我都是每條評論必回,每一個郵件也必回:數據庫
我自信這一年多以來,對netcore的基礎知識已經瞭解的七七八八了,基本都能回答些,可是每當有人問到 IdentityServer4 的相關內容的時候,我都稍微捉襟見肘,雖然我寫了四篇文章,可是由於中間卡了一個心結(具體內容下文會說明),因此沒有進行下去,也讓本身沒有進一步去研究這個框架的動力了,你們確定都懂那個心理,若是一直有個刺,而後時間長了會刻意迴避它。後端
不過最後我仍是決定要搞起來,既然說到了要佈道,就要走下去,因此我會除了以前的四篇文章外,還再有三到四篇的文章來開啓 Ids4 的第二階段的學習,而後配合還有大概八個視頻的講解,若是你看過個人第一個系列視頻教程,應該內心有譜,我第二個系列講的怎麼樣,因此我也就很少說了,這兩週準備一下,下週末開啓視頻講解第二系列。api
那下面咱們就立刻開啓今天的這篇文章吧。服務器
還記得我開啓 IdentityServer4 講解是在半年前,當時我本想是八篇文章,將個人全部項目 —— 主要是 Blog.Admin 和 Blog.Vue 這兩個項目統一集成到 Ids4 的網關受權上來,固然有精力也能夠把 DDD 和 Nuxt 的認證也添加進來,只不過 DDD 已經用了 Identity 了,這個優先級能夠暫時日後放放,而後就寫了四篇文章,主要是偏重於實戰,而不是講解那老生常談的知識點:框架
可是在寫到了第四篇文章的時候,出現了一個說小不小,說大不大的問題,讓我擱置了整整半年,是什麼問題,我簡單說說:dom
我看博客園不少博主在講 Ids4 的時候,基本狀況都是用的無狀態的認證方式,什麼意思呢?分佈式
一、就是應用場景都是對應的 [Authorize] 這種只要登陸了就能夠的項目裏,沒有涉及到複雜的策略受權,好比角色和模塊;
二、而後你可能也會說,「 我看到他們文章講解中生成的 token 中,能夠自定義 Role 到 Claim 裏呀,你直接在 Blog.Core 項目獲取到 Role 進行策略受權不就好了」,你說的沒錯,可是這裏有一個後續問題;
三、那個人 Role 信息在哪裏管理?是在 Blog.Ids4 (認證服務)項目,仍是在 Blog.Core (業務資源服務)項目裏?
這裏你能夠稍微暫停一下,暫停五分鐘,本身想想,如何去解決這些問題,特別是第三個問題。
若是你把 Role 的信息管理放到了 Blog.Ids4 項目裏,那 Blog.Core 如何針對 Role 進行匹配 Url進行受權配置呢?
可是若是把 Role 管理放到了 Blog.Core 項目裏,那就沒有辦法根據 UName 和 Pwd 生成 token 的時候,在 Claims 裏生成 Role 信息了。
這個並無那麼簡單喲,固然若是大家公司開發過,能夠直接看下文,和我想的方案對比下,若是有出入,或者你的更好,我熱烈歡迎提出批評和指導建議,好了,那我就說說個人三種思路吧。
這種方案呢,剛剛咱們在上文已經說到了,我也已經實現了,就是在文末個人項目中,已經實現這個了, 就是 Blog.Ids4 只單單提供認證功能,不用管 Role 的相關聲明 Claims,基本都是對應的前臺項目,好比咱們的博客項目和電商項目,用戶登陸了就行,就能夠直接發文章或者購買商品了,不用理睬具體啥頁面不能訪問,這個就很少說了,很好理解。
這種場景,很好解決,認證服務項目和資源服務項目 相互獨立,沒有交際,只是提供一個認證網關的做用,這裏就很少說了。
可是這種狀況有時候並非不少,或者說是少數的,咱們更多的,仍是須要在 token 中攜帶 role 的 claim 聲明,特別是後臺管理系統,都是有狀態的受權,好比咱們的 Blog.Core 是比較複雜的策略受權,那這個時候就須要討論一下數據庫的問題了,其實重點仍是討論 Role 表是在哪一個項目維護的問題。
那麼問題就來了,咱們爲了知足複雜的策略受權,就須要在 Blog.Core 項目裏將 Role 和 Url/Api 進行匹配映射到數據庫,那就必須用 Role 表。
可是咱們上邊也討論不少了,咱們必需要在 token 中攜帶 Role 的Claim,那就必須放到 Blog.Ids4 項目裏維護 Role。
這個時候是否是發現兩種狀況很矛盾,爲了達到這個項目,我簡單看了看 ABP 項目,這個仍是羣管理 @Kawhi 提的建議,我獲得了一絲絲的想法,ABP項目是把認證和資源服務合併到了一塊兒!
這個我最終決定採用的方案,這個方案已經放棄,我如今Blog.Core資源服務器已經支持多庫了,能夠不用合併了,
具體代碼我已經慢慢的在 Ids4 項目裏遷移修改了,感興趣的能夠看看,其實說白了,就是把 EFCore 生成表結構的數據庫,指向 Blog.Core 項目的就好了,而後這個時候,咱們就看到了兩個 Role 表:
那既然咱們的 Ids4 項目用的是 AspNetRoles 來進行認證的,咱們直接用這個表不就行了?!,捨棄下邊的 Role 表,用上邊 Ids4 自帶的 AspNetRoles 表,來和咱們的 Module 和 Permission 表就行受權映射匹配,這樣是否是完美的解決了咱們上邊出現的全部問題!
而後咱們的 User 管理和 Role 管理,都移交到了 Ids4 項目裏,從而使得咱們的 Blog.Coe 資源服務器只須要踏踏實實的作受權就好了:
這個不用擔憂看不懂,我在後邊的文章和視頻中也會詳細說到,本文主要說的是這個思路,具體業務邏輯和代碼,我會詳細講解的,你能看懂個人意思就行。
這樣是否是很好的解決了 Role 管理的問題,並且能夠快速的將 Blog.Admin 和 Vue 項目給切換過來,很簡單。可是,萬事就怕可是😂,這裏有一個問題,就是若是我有多個資源服務器怎麼辦,多個資源服務器確定是不能和一個認證數據庫合併的,好比個人項目結構是這樣的:
這種咱們是很差去把 資源服務器和 認證中心的數據庫放到一塊兒的,固然這種微服務的方案也不是這麼玩兒的,我之後會繼續說到這種狀況,如何來設計。
我們先不說微服務,就說單一服務,那若是不能數據庫合併,又想保證 Role 的良好維護,我想了不是很好的辦法,一共分下邊幾種狀況。
既然不放到一塊兒,那就分離開,仍是我目前項目 Github 上的狀況,兩個數據庫,兩個 Role 表 ,可是呢,對 Role 的管理,仍是放到 Ids4 服務器,
只不過這個時候,須要在資源服務器 Blog.Core 裏,寫一個定時器或者服務,將 Ids4 Db 中的 AspNetRoles 表數據,統一導入到 Blog.Core Db 的 Roles 表中,而後咱們在資源服務器仍是來操做 Roles 表,基本個人資源服務器修改的代碼不多,只是多了一個數據同步的方法而已,
相對於上邊的方案,這個優勢是:
一、代碼改動小;
二、多個資源服務器能夠共存,共用一個認證中心;
三、防止由於 IdentityServer4 官方更新,而破壞咱們的資源服務代碼,侵入性小。
缺點也是有的,就是比較 low,並且不能保證明時性,更新速度受到定時器的限制。那和老李討論一下,他給的建議是,能夠在不使用表同步,而使用接口的形式,請往下看。
這種方案,最終被我 PASS 了,思路我簡單說下,其實很簡單,就是咱們的資源服務器 Role 表棄用,整個項目統一用 Ids4 認證服務器提供一個對外暴露的 GetRoles 的 api 接口,來保證明時性和統一性,
可是這樣缺點太明顯,受官網的限制,並且對資源服務器的侵入性太強,儘管能夠封裝一個方法。
說這個的目的,只是想讓你們集思廣益,開拓思惟,學習都是思考的過程。
這個方案是有條件的,資源服務器必須是支持多庫操做的,目前個人Blog.Core項目已經支持了多庫操做,配置一下,就能夠獲取 Blog.Idp 項目中的 Role 信息了,是很方便的。
可是若是你的資源服務器不支持多庫操做,那我仍是建議使用第一種方案(數據庫合併),和第三種吧(經過 idp 項目提供一個role的接口)。
這個是一個不肯透露姓名的羣友的建議,我原本想放到其餘方案裏,可是感受也是很不錯的,這裏單放出來,我我的也沒有考慮到他的這一點 —— 抽離出 Role 管理中心,作分佈式服務給 認證中心。
具體來講是什麼意思呢,我這裏繼續畫一個圖就知道了:
這樣不只能夠解決 Role 同步問題,還能很好的進行擴展,咱們不管增長多少個 資源服務器,只須要向 Role 管理中心,推送相應的Role就行,而後咱們的 Ids4 認證中心,只須要從 Role 管理中心獲取,你能夠經過資源服務器的 domain 來作區分,來管理 User。
具體的請看下邊的評論喲,評論也很精彩!!!
除了我上邊提出來的一些方案,若是你有什麼想法,或者好的注意,能夠文章下邊留言或者評論,不勝感激,好比:
一、@老張說:不在資源服務器裏進行數據庫的映射匹配,所有寫到Controller控制器的特性上的角色或模塊受權[Authorize(Roles = "Admin,Client")],這樣也能解決。
二、@你們說:這裏我就不寫名字了,評論區的小夥伴較多的仍是採用【拆分服務,合併數據庫】的模式,這樣代碼也不會亂,數據也很好同步效果。
期待你的熱評!
https://github.com/anjoy8/Blog.IdentityServer
原文出處:https://www.cnblogs.com/laozhang-is-phi/p/11844395.html