【.NETCore 3】Ids4 ║ 多项目集成统一认证中心的思考
?前言
哈嘍大家好,好久都沒有寫文章了,這次又重新開始寫技術(shù)文章了,半年前我還是一直保持每周都寫文章的,后來是為了響應(yīng)群友的號召,開始踏上了錄制視頻(https://www.bilibili.com/video/av58096866),直播授課(https://live.bilibili.com/21507364)的道路,目前看來效果還算基本及格吧,雖然人氣沒有那些大佬的多,不過我也是一直很盡心力,包括字幕的錄入,每周三定期的講課,不過真的很累,但是自認(rèn)為做的還可以了,只是沒能申請上MVP🙃。
?
為什么突然想要寫文章了呢,我是有強(qiáng)迫癥的,目前開源了五個(gè)系列的文章,從 NetCore 到 Vue,從 Admin 到 Nuxt,然后從 DDD 到 IdentityServer4,我自認(rèn)為都是貼近實(shí)戰(zhàn)的,因?yàn)榭吹侥承┬』锇檎f,應(yīng)用到了公司的項(xiàng)目里,我也是很開心,而且 NetCore 項(xiàng)目的Github start 數(shù)也破千了,我感謝每一個(gè)點(diǎn)贊評論的小伙伴,我都是每條評論必回,每個(gè)郵件也必回:
我自信這一年多以來,對netcore的基礎(chǔ)知識已經(jīng)了解的七七八八了,基本都能回答些,但是每當(dāng)有人問到 IdentityServer4 的相關(guān)內(nèi)容的時(shí)候,我都稍微捉襟見肘,雖然我寫了四篇文章,但是因?yàn)橹虚g卡了一個(gè)心結(jié)(具體內(nèi)容下文會(huì)說明),所以沒有進(jìn)行下去,也讓自己沒有進(jìn)一步去研究這個(gè)框架的動(dòng)力了,大家肯定都懂那個(gè)心理,如果一直有個(gè)刺,然后時(shí)間長了會(huì)刻意回避它。
?
不過最后我還是決定要搞起來,既然說到了要布道,就要走下去,所以我會(huì)除了之前的四篇文章外,還再有三到四篇的文章來開啟 Ids4 的第二階段的學(xué)習(xí),然后配合還有大概八個(gè)視頻的講解,如果你看過我的第一個(gè)系列視頻教程,應(yīng)該心里有譜,我第二個(gè)系列講的怎么樣,所以我也就不多說了,這兩周準(zhǔn)備一下,下周末開啟視頻講解第二系列。
那下面我們就馬上開啟今天的這篇文章吧。
?
?
?零、回顧與目標(biāo)
?
還記得我開啟 IdentityServer4 講解是在半年前,當(dāng)時(shí)我本想是八篇文章,將我的所有項(xiàng)目 —— 主要是 Blog.Admin 和 Blog.Vue 這兩個(gè)項(xiàng)目統(tǒng)一集成到 Ids4 的網(wǎng)關(guān)授權(quán)上來,當(dāng)然有精力也可以把 DDD 和 Nuxt 的認(rèn)證也添加進(jìn)來,只不過 DDD 已經(jīng)用了 Identity 了,這個(gè)優(yōu)先級可以暫時(shí)往后放放,然后就寫了四篇文章,主要是偏重于實(shí)戰(zhàn),而不是講解那老生常談的知識點(diǎn):
?
01 ║ 授權(quán)服務(wù)器 IdentityServer4 開篇講&計(jì)劃書
02 ║ 基礎(chǔ)知識集合 & 項(xiàng)目搭建一
03 ║ 詳解授權(quán)持久化 & 用戶數(shù)據(jù)遷移
04 ║ 用戶數(shù)據(jù)管理 & 前后端授權(quán)聯(lián)調(diào)
?
但是在寫到了第四篇文章的時(shí)候,出現(xiàn)了一個(gè)說小不小,說大不大的問題,讓我擱置了整整半年,是什么問題,我簡單說說:
我看很多博主在講 Ids4 的時(shí)候,基本情況都是用的無狀態(tài)的認(rèn)證方式,什么意思呢?
1、就是應(yīng)用場景都是對應(yīng)的 [Authorize] 這種只要登錄了就可以的項(xiàng)目里,沒有涉及到復(fù)雜的策略授權(quán),比如角色和模塊;
2、然后你可能也會(huì)說,“ 我看到他們文章講解中生成的 token 中,可以自定義 Role 到 Claim 里呀,你直接在 Blog.Core 項(xiàng)目獲取到 Role 進(jìn)行策略授權(quán)不就行了”,你說的沒錯(cuò),但是這里有一個(gè)后續(xù)問題;
3、那我的 Role 信息在哪里管理?是在 Blog.Ids4 (認(rèn)證服務(wù))項(xiàng)目,還是在 Blog.Core (業(yè)務(wù)資源服務(wù))項(xiàng)目里?
這里你可以稍微暫停一下,暫停五分鐘,自己想一想,如何去解決這些問題,特別是第三個(gè)問題。
如果你把 Role 的信息管理放到了 Blog.Ids4 項(xiàng)目里,那 Blog.Core 如何針對 Role 進(jìn)行匹配 Url進(jìn)行授權(quán)配置呢?
但是如果把 Role 管理放到了 Blog.Core 項(xiàng)目里,那就沒有辦法根據(jù) UName 和 Pwd 生成 token 的時(shí)候,在 Claims 里生成 Role 信息了。
?
這個(gè)并沒有那么簡單喲,當(dāng)然如果你們公司開發(fā)過,可以直接看下文,和我想的方案對比下,如果有出入,或者你的更好,我熱烈歡迎提出批評和指導(dǎo)建議,好了,那我就說說我的三種思路吧。
?
?一、無狀態(tài)的簡單授權(quán)認(rèn)證
?
這種方案呢,剛剛我們在上文已經(jīng)說到了,我也已經(jīng)實(shí)現(xiàn)了,就是在文末我的項(xiàng)目中,已經(jīng)實(shí)現(xiàn)這個(gè)了, 就是 Blog.Ids4 只單單提供認(rèn)證功能,不用管 Role 的相關(guān)聲明 Claims,基本都是對應(yīng)的前臺項(xiàng)目,比如我們的博客項(xiàng)目和電商項(xiàng)目,用戶登錄了就行,就可以直接發(fā)文章或者購買商品了,不用理睬具體啥頁面不能訪問,這個(gè)就不多說了,很好理解。
這種場景,很好解決,認(rèn)證服務(wù)項(xiàng)目和資源服務(wù)項(xiàng)目 相互獨(dú)立,沒有交際,只是提供一個(gè)認(rèn)證網(wǎng)關(guān)的作用,這里就不多說了。
?
但是這種情況有時(shí)候并不是很多,或者說是少數(shù)的,我們更多的,還是需要在 token? 中攜帶 role 的 claim 聲明,特別是后臺管理系統(tǒng),都是有狀態(tài)的授權(quán),比如我們的 Blog.Core 是比較復(fù)雜的策略授權(quán),那這個(gè)時(shí)候就需要討論一下數(shù)據(jù)庫的問題了,其實(shí)重點(diǎn)還是討論 Role 表是在哪個(gè)項(xiàng)目維護(hù)的問題。
?
?
?二、有狀態(tài)的授權(quán)認(rèn)證中心
?
那么問題就來了,我們?yōu)榱藵M足復(fù)雜的策略授權(quán),就需要在 Blog.Core 項(xiàng)目里將 Role 和 Url/Api 進(jìn)行匹配映射到數(shù)據(jù)庫,那就必須用 Role 表。
但是我們上邊也討論很多了,我們必須要在 token 中攜帶 Role 的Claim,那就必須放到 Blog.Ids4 項(xiàng)目里維護(hù) Role。
這個(gè)時(shí)候是不是發(fā)現(xiàn)兩種情況很矛盾,為了達(dá)到這個(gè)項(xiàng)目,我簡單看了看 ABP 項(xiàng)目,這個(gè)還是群管理 @Kawhi 提的建議,我得到了一絲絲的想法,ABP項(xiàng)目是把認(rèn)證和資源服務(wù)合并到了一起!
?
?1、認(rèn)證數(shù)據(jù)庫與業(yè)務(wù)數(shù)據(jù)庫合二為一
?
這個(gè)我最終決定采用的方案,具體代碼我已經(jīng)慢慢的在 Ids4 項(xiàng)目里遷移修改了,感興趣的可以看看,其實(shí)說白了,就是把 EFCore 生成表結(jié)構(gòu)的數(shù)據(jù)庫,指向 Blog.Core 項(xiàng)目的就行了,然后這個(gè)時(shí)候,我們就看到了兩個(gè) Role 表:
?
那既然我們的 Ids4 項(xiàng)目用的是 AspNetRoles 來進(jìn)行認(rèn)證的,我們直接用這個(gè)表不就好了?!,舍棄下邊的 Role 表,用上邊 Ids4 自帶的 AspNetRoles 表,來和我們的 Module 和 Permission 表就行授權(quán)映射匹配,這樣是不是完美的解決了我們上邊出現(xiàn)的所有問題!
?
然后我們的 User 管理和 Role 管理,都移交到了 Ids4 項(xiàng)目里,從而使得我們的 Blog.Coe 資源服務(wù)器只需要踏踏實(shí)實(shí)的做授權(quán)就行了:
?
?
這個(gè)不用擔(dān)心看不懂,我在后邊的文章和視頻中也會(huì)詳細(xì)說到,本文主要說的是這個(gè)思路,具體業(yè)務(wù)邏輯和代碼,我會(huì)詳細(xì)講解的,你能看懂我的意思就行。?
這樣是不是很好的解決了 Role 管理的問題,而且可以快速的將 Blog.Admin 和 Vue 項(xiàng)目給切換過來,很簡單。但是,萬事就怕但是😂,這里有一個(gè)問題,就是如果我有多個(gè)資源服務(wù)器怎么辦,多個(gè)資源服務(wù)器肯定是不能和一個(gè)認(rèn)證數(shù)據(jù)庫合并的,比如我的項(xiàng)目結(jié)構(gòu)是這樣的:
?
?
這種我們是不好去把 資源服務(wù)器和 認(rèn)證中心的數(shù)據(jù)庫放到一起的,當(dāng)然這種微服務(wù)的方案也不是這么玩兒的,我以后會(huì)繼續(xù)說到這種情況,如何來設(shè)計(jì)。
咱們先不說微服務(wù),就說單一服務(wù),那如果不能數(shù)據(jù)庫合并,又想保證 Role 的良好維護(hù),我想了不是很好的辦法,一共分兩種情況。
?
?2、認(rèn)證DB與資源DB分離,兩個(gè)Role表
既然不放到一起,那就分離開,還是我目前項(xiàng)目 Github 上的情況,兩個(gè)數(shù)據(jù)庫,兩個(gè) Role 表 ,但是呢,對 Role 的管理,還是放到 Ids4 服務(wù)器,
只不過這個(gè)時(shí)候,需要在資源服務(wù)器 Blog.Core 里,寫一個(gè)定時(shí)器或者服務(wù),將 Ids4 Db 中的 AspNetRoles 表數(shù)據(jù),統(tǒng)一導(dǎo)入到 Blog.Core Db 的 Roles 表中,然后我們在資源服務(wù)器還是來操作 Roles 表,基本我的資源服務(wù)器修改的代碼很少,只是多了一個(gè)數(shù)據(jù)同步的方法而已,
相對于上邊的方案,這個(gè)優(yōu)點(diǎn)是:
1、代碼改動(dòng)小;
2、多個(gè)資源服務(wù)器可以共存,共用一個(gè)認(rèn)證中心;
3、防止因?yàn)?IdentityServer4 官方更新,而破壞我們的資源服務(wù)代碼,侵入性小。
?
缺點(diǎn)也是有的,就是比較 low,而且不能保證實(shí)時(shí)性,更新速度受到定時(shí)器的限制。那和老李討論一下,他給的建議是,可以在不使用表同步,而使用接口的形式,請往下看。
?
?3、認(rèn)證DB與資源DB分離,一個(gè)Role表
這種方案,最終被我 PASS 了,思路我簡單說下,其實(shí)很簡單,就是我們的資源服務(wù)器 Role 表?xiàng)売?#xff0c;整個(gè)項(xiàng)目統(tǒng)一用 Ids4 認(rèn)證服務(wù)器提供一個(gè)對外暴露的 GetRoles 的 api 接口,來保證實(shí)時(shí)性和統(tǒng)一性,
但是這樣缺點(diǎn)太明顯,受官網(wǎng)的限制,而且對資源服務(wù)器的侵入性太強(qiáng),盡管可以封裝一個(gè)方法。
說這個(gè)的目的,只是想讓大家集思廣益,開拓思維,學(xué)習(xí)都是思考的過程。
?
?
?
?三、其他方案
?除了我上邊提出來的一些方案,如果你有什么想法,或者好的注意,可以文章下邊留言或者評論,不勝感激,比如:
1、@老張說:不在資源服務(wù)器里進(jìn)行數(shù)據(jù)庫的映射匹配,全部寫到Controller控制器的特性上的角色或模塊授權(quán)[Authorize(Roles = "Admin,Client")],這樣也能解決。
2、???
?
期待你的熱評!?
?
?
四、Github && Gitee
?
https://github.com/anjoy8/Blog.IdentityServer
?
總結(jié)
以上是生活随笔為你收集整理的【.NETCore 3】Ids4 ║ 多项目集成统一认证中心的思考的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WeihanLi.Npoi 近期更新
- 下一篇: .NET 社区 NB,2019 中国 .