【Ids4实战】最全的 v4 版本升级指南
(恰似一江春水向東流)
最近聽(tīng)說(shuō)IdentityServer4從v3升級(jí)到v4了,其實(shí)很簡(jiǎn)單,就是nuget包升級(jí)一下的事兒,不過(guò)沒(méi)想到涉及到的內(nèi)容還挺多,要不然也不會(huì)直接從3.1直接蹦到4.0,這么大的跨度,證明已經(jīng)涉及到核心的類做了修改。
不要抱怨一直修改,畢竟已經(jīng)很多人寫(xiě)了更新文檔了,軟件系統(tǒng)就是一直更新的過(guò)程。當(dāng)然,如果不更新使用v3也可以,功能幾乎都是一樣的,但是我更喜歡更新到最新版本。相關(guān)代碼已經(jīng)放到了項(xiàng)目的4x分支(如果沒(méi)有,說(shuō)明已經(jīng)上線,并遷到主分支了):
已經(jīng)通過(guò)docker部署好了,現(xiàn)在大家看到的online效果,就是4x版本的。那下邊就快速說(shuō)說(shuō)更新過(guò)程吧,放心,前方安全,并沒(méi)有涉及到什么看不懂的原理。
最終更新的文件這么多:
01
PART
升級(jí)依賴包
升級(jí)肯定要從nuget包開(kāi)始,以下這幾個(gè)就是我認(rèn)證中心項(xiàng)目使用的nuget包,一鍵升級(jí)全部,可以看到都是最新的了:
(升級(jí)nuget包)
操作確實(shí)是很簡(jiǎn)單,操作也在預(yù)料之中,只不過(guò)沒(méi)想到會(huì)這么多(其實(shí)更多,因?yàn)檫@里僅僅是編譯下的Errors,有些頁(yè)面內(nèi)的還沒(méi)有被編譯到):
那下邊就開(kāi)始動(dòng)手遷移吧,再問(wèn)一下自己,是否準(zhǔn)備好了,3x版其實(shí)也可以。
02
PART
尋找模板
以下的是我的摸索歷程,畢竟我看的代碼和文章基本都是3x的。
01
更新官方模板
上邊我們僅僅是更新了Ids4的核心庫(kù),我想象著官方既然更新了核心庫(kù),那他們的模板庫(kù)已經(jīng)也已經(jīng)更新了,然后就卸載了這幾個(gè)模板,又重新安裝了一次:
相關(guān)的安裝命令是這樣的:
因?yàn)槲矣玫氖强焖賳?dòng)項(xiàng)目,所以就直接生成了一個(gè)is4admin的項(xiàng)目,發(fā)現(xiàn),事情并沒(méi)有我想象的那么簡(jiǎn)單,他們基本還是3x版本的。
其實(shí)有一個(gè)是4x版本的,就是is4inmem版本的:
他這個(gè)是4x版本的,只不過(guò)是內(nèi)存模式的,有很多地方還是和我們的不一樣,沒(méi)辦法,只能尋找官網(wǎng)了。
02
查看源碼
其實(shí)官方的源碼很多也都還是3x版本的,畢竟模板都是這樣,直接用文件查找的方式,一一的點(diǎn)開(kāi)來(lái)看,最終還是找到了:
當(dāng)然官網(wǎng)有很多地方,最終我是在host文件夾下,才發(fā)現(xiàn)了4x版本的快速啟動(dòng)代碼,然后開(kāi)始針對(duì)錯(cuò)誤一一的處理,主要的修改的地方有以下幾個(gè)部分。
03
PART
主要修復(fù)部分
01
DB上下文部分
其實(shí)大家根據(jù)上邊的報(bào)錯(cuò)一一修改就行了,我這里簡(jiǎn)單的列舉下,心里有個(gè)譜。
本次升級(jí)到4x,數(shù)據(jù)庫(kù)發(fā)生了變化,除了增加表以外,比如增加了IdentityResourceClaims表,然后也針對(duì)幾個(gè)表,增刪修改了幾列字段,具體的我在下文會(huì)列舉出來(lái),自己更新的時(shí)候也可以看到,
所以我們就需要重新生成遷移報(bào)告和update數(shù)據(jù)庫(kù)了,大家做好生產(chǎn)數(shù)據(jù)的備份和保護(hù)。
如果你不更新數(shù)據(jù)庫(kù)遷移的話,肯定會(huì)遇到這個(gè)錯(cuò)誤的:
除了修改了數(shù)據(jù)庫(kù)表結(jié)構(gòu),也同時(shí)配套了幾個(gè)數(shù)據(jù)庫(kù)腳本,方便我們使用,具體的查看官方源碼即可,基本的更新內(nèi)容這些:
遷移到ConfigurationDbContext的新模式需要做以下更改:
添加列:Clients、ApiResources、apiscope和ApiScopeClaims
移除列:ApiScopeClaims和ApiScope
重命名表:ApiClaims、ApiProperties、ApiSecrets、IdentityClaims和IdentityProperties
添加表:添加兩個(gè)新表——ApiResourceScopes和ApiResourceProperties
有關(guān)新的范圍和資源建模的更多細(xì)節(jié),請(qǐng)參考IdentityServer4文檔。
遷移到PersistedGrantDbContext的新模式需要做以下更改:
新列:為DeviceCodes和PersistedGrants添加列
為了使轉(zhuǎn)換更容易,我們創(chuàng)建了幾個(gè)腳本,涵蓋四種不同的數(shù)據(jù)庫(kù)類型:
MySQL
MsSQL
PostgreSQL
SQLite
可以看到這次升級(jí),只是Ids4相關(guān)的組件庫(kù),并沒(méi)有涉及到微軟的Identity類庫(kù)七個(gè)用戶相關(guān)的表,所以用戶數(shù)據(jù)不會(huì)丟失。也不用遷移用戶數(shù)據(jù)。
PS:遷移的時(shí)候,如果是用我的項(xiàng)目,手動(dòng)執(zhí)行下那四個(gè)命令,不過(guò)相信每個(gè)玩過(guò)efcore的都明白如何操作:
1、PM> add-migration InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb 2、PM> update-database -c PersistedGrantDbContext 3、PM> add-migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb 4、PM> update-database -c ConfigurationDbContext//?因?yàn)椴挥眠w移用戶數(shù)據(jù),所以不用管用戶上下文整個(gè)過(guò)程沒(méi)有報(bào)錯(cuò),雖然它提示說(shuō)可能造成數(shù)據(jù)丟失,但是并沒(méi)有
很流暢的就下來(lái)了,只是最后有一個(gè)小插曲,就是遷移好后,然后重新生成了容器鏡像等,前端admin項(xiàng)目訪問(wèn)的時(shí)候,提示沒(méi)有scope,后來(lái)發(fā)現(xiàn)Enabled為false了,不知什么時(shí)候被改了,修改為true就行了。
除了這個(gè)小插曲,文末的問(wèn)題才是最重要的,但是也是很簡(jiǎn)單的,不要慌,往下看就是了。
02
控制器API方面
既然我們的數(shù)據(jù)庫(kù)表結(jié)構(gòu)都變了,那控制器的一些API和視頻模型肯定也會(huì)有變化的,這是肯定的,具體我就不好列舉了,涵蓋以下幾個(gè)部分:
AccountController、ConsentController、DeviceController、GrantsController、這四部分。
其實(shí)不要感覺(jué)更新的內(nèi)容很多,都是很簡(jiǎn)單的幾處,自己稍微看一看,或者用上邊官方源代碼覆蓋下就好了。
03
視圖部分
理所應(yīng)當(dāng)?shù)?#xff0c;視圖模型變了,那我們的頁(yè)面也需要調(diào)整:
就是這么多,對(duì)應(yīng)修改下就行了。
整個(gè)過(guò)程大概持續(xù)了30~60分鐘,全程并沒(méi)有很難受的地方,都是粘貼復(fù)制啥的。只要心靜就可快速搞定。
更新完成以后,可以看到項(xiàng)目已經(jīng)沒(méi)有問(wèn)題了,但是這個(gè)時(shí)候還會(huì)剩下一個(gè)小知識(shí)點(diǎn),看startup.cs就知道了。
04
PART
配置源地址
如果你之前用過(guò)Ids4,肯定都知道那個(gè)梗,就是本地開(kāi)發(fā)的時(shí)候一切正常,如果配置到服務(wù)器,源地址一直是localhost域名,之前我也寫(xiě)過(guò)一篇文章來(lái)講如何處理這個(gè)問(wèn)題,主要就是用到的是上邊截圖中,配置PublicOrigin這個(gè)屬性即可,但是這次在4x版本中,這個(gè)api被刪掉了。
如果你不做配置的話,會(huì)看到這個(gè)情況:
找了很多資料,最后還是在官方開(kāi)源項(xiàng)目的Issue中發(fā)現(xiàn)了,看來(lái)還是得多看Issue,可能官方也發(fā)現(xiàn)3x升級(jí)4x有很多問(wèn)題,干脆直接Pinned了一個(gè)issue:
最終的解決方案其實(shí)有兩種,第一種很簡(jiǎn)單,直接在中間件的最外層,也就是最上邊,添加配置:
app.Use(async (ctx, next) =>{ctx.SetIdentityServerOrigin("https://xxx.com");await next();});其實(shí)就是SetIdentityServerOrigin方法。
第二種就稍微復(fù)雜了些,需要三步:
配置服務(wù):
services.Configure<ForwardedHeadersOptions>(options => {options.ForwardedHeaders =ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;options.KnownNetworks.Clear();options.KnownProxies.Clear(); });配置中間件:
app.UseForwardedHeaders();配置Nginx:
proxy_set_header X-Forwarded-Host $host:$proxy_port;看自己的安排和喜好吧。
05
PART
校驗(yàn)Token
果然不出意外,報(bào)錯(cuò)了,是在Admin項(xiàng)目發(fā)起登錄,獲取token后,一直刷新,不能獲取資源服務(wù)器的API,一直401,解析token查看,缺少字段:
大家可以看到,左側(cè)遷移后的Token令牌竟然少了幾個(gè)關(guān)鍵Claims,一定是哪里沒(méi)有配置,
這里先大膽猜測(cè)下,我們能登錄,證明用戶系統(tǒng)沒(méi)問(wèn)題;
我們可以獲取token,證明客戶端Clients配置沒(méi)問(wèn)題;
但是一直401,缺少字段,那肯定是我們的資源服務(wù)確實(shí)對(duì)應(yīng)的scope。
然后我各種檢查,發(fā)現(xiàn)都是一樣的數(shù)據(jù),最后我想到了文章上邊說(shuō)到的官方除了增加幾個(gè)字段以外,還增加了兩個(gè)表,然后找了找資料,發(fā)現(xiàn)4x版本已經(jīng)更新了,以前的時(shí)候,我們只需要針對(duì)客戶端配置資源api就行了,比如這樣:
但是如果你看一下剛剛新建的數(shù)據(jù)庫(kù),可以發(fā)現(xiàn)ApiScopes表已經(jīng)沒(méi)有了ApiResources表的外鍵了,所以需要在新增的表ApiResourceScopes中進(jìn)行配置:
相當(dāng)于做了一個(gè)跳板,當(dāng)然你也可以說(shuō)做了一個(gè)更復(fù)雜的關(guān)系表,因?yàn)檫@樣的話,我們就可以針對(duì)一個(gè)資源服務(wù)器做多個(gè)Scope鑒權(quán)了,比如我們Blog.Core項(xiàng)目,我們可以分成好幾個(gè)scope來(lái)鑒權(quán),就像把一個(gè)資源服務(wù)器,拆成了多個(gè)一樣,是不是又高級(jí)了!
到了這里,基本就已經(jīng)遷移完成了,整個(gè)過(guò)程一個(gè)小時(shí),當(dāng)然你還需要部署什么的,也不難,我建議沒(méi)有充裕的時(shí)間,還是用v3吧,如果自己不想折騰。
參考鏈接:
1、
https://github.com/IdentityServer/IdentityServer4/issues/4592
2、
https://www.identityserver.com/articles/migrating-your-identityserver4-v3-database-to-identityserver4-v4
3、
https://stackoverflow.com/questions/62713022/dotnet-core-identityserver4-reverse-proxy
4、
https://www.cnblogs.com/xhznl/p/13223964.html
彩蛋(2222):
總結(jié)
以上是生活随笔為你收集整理的【Ids4实战】最全的 v4 版本升级指南的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Golden Master Patter
- 下一篇: [译]使用DOT语言和GraphvizO