隐藏

【Ids4实战】最全的 v4 版本升级指南

发布:2021/1/27 16:11:27作者:管理员 来源:本站 浏览次数:940

最近听说IdentityServer4从v3升级到v4了,其实很简单,就是nuget包升级一下的事儿,不过没想到涉及到的内容还挺多,要不然也不会直接从3.1直接蹦到4.0,这么大的跨度,证明已经涉及到核心的类做了修改。


不要抱怨一直修改,毕竟已经很多人写了更新文档了,软件系统就是一直更新的过程。当然,如果不更新使用v3也可以,功能几乎都是一样的,但是我更喜欢更新到最新版本。相关代码已经放到了项目的4x分支(如果没有,说明已经上线,并迁到主分支了):

图片


已经通过docker部署好了,现在大家看到的online效果,就是4x版本的。那下边就快速说说更新过程吧,放心,前方安全,并没有涉及到什么看不懂的原理。

最终更新的文件这么多:

图片



01
PART
升级依赖包


升级肯定要从nuget包开始,以下这几个就是我认证中心项目使用的nuget包,一键升级全部,可以看到都是最新的了:

图片

(升级nuget包)


操作确实是很简单,操作也在预料之中,只不过没想到会这么多(其实更多,因为这里仅仅是编译下的Errors,有些页面内的还没有被编译到):

图片


那下边就开始动手迁移吧,再问一下自己,是否准备好了,3x版其实也可以。




02
PART
寻找模板


以下的是我的摸索历程,毕竟我看的代码和文章基本都是3x的。


01

更新官方模板

上边我们仅仅是更新了Ids4的核心库,我想象着官方既然更新了核心库,那他们的模板库已经也已经更新了,然后就卸载了这几个模板,又重新安装了一次:

图片


相关的安装命令是这样的:





// 安装模板dotnet new -i IdentityServer4.Templates// 初始化项目dotnet new is4admin --name Idp

因为我用的是快速启动项目,所以就直接生成了一个is4admin的项目,发现,事情并没有我想象的那么简单,他们基本还是3x版本的。

其实有一个是4x版本的,就是is4inmem版本的:


dotnet new is4inmem --name Idp

他这个是4x版本的,只不过是内存模式的,有很多地方还是和我们的不一样,没办法,只能寻找官网了。


02

查看源码

其实官方的源码很多也都还是3x版本的,毕竟模板都是这样,直接用文件查找的方式,一一的点开来看,最终还是找到了:


https://github.com/IdentityServer/IdentityServer4/tree/main/src/AspNetIdentity/host/Quickstart


当然官网有很多地方,最终我是在host文件夹下,才发现了4x版本的快速启动代码,然后开始针对错误一一的处理,主要的修改的地方有以下几个部分。



03
PART
主要修复部分


01

DB上下文部分

其实大家根据上边的报错一一修改就行了,我这里简单的列举下,心里有个谱。


本次升级到4x,数据库发生了变化,除了增加表以外,比如增加了IdentityResourceClaims表,然后也针对几个表,增删修改了几列字段,具体的我在下文会列举出来,自己更新的时候也可以看到,

图片


所以我们就需要重新生成迁移报告和update数据库了,大家做好生产数据的备份和保护


如果你不更新数据库迁移的话,肯定会遇到这个错误的:


图片


除了修改了数据库表结构,也同时配套了几个数据库脚本,方便我们使用,具体的查看官方源码即可,基本的更新内容这些:

迁移到ConfigurationDbContext的新模式需要做以下更改:


添加列:Clients、ApiResources、apiscope和ApiScopeClaims
移除列:ApiScopeClaims和ApiScope
重命名表:ApiClaims、ApiProperties、ApiSecrets、IdentityClaims和IdentityProperties
添加表:添加两个新表——ApiResourceScopes和ApiResourceProperties

有关新的范围和资源建模的更多细节,请参考IdentityServer4文档。

迁移到PersistedGrantDbContext的新模式需要做以下更改:
新列:为DeviceCodes和PersistedGrants添加列


为了使转换更容易,我们创建了几个脚本,涵盖四种不同的数据库类型:
MySQL
MsSQL
PostgreSQL
SQLite

可以看到这次升级,只是Ids4相关的组件库,并没有涉及到微软的Identity类库七个用户相关的表,所以用户数据不会丢失。也不用迁移用户数据。


图片


PS:迁移的时候,如果是用我的项目,手动执行下那四个命令,不过相信每个玩过efcore的都明白如何操作:







1PM> add-migration InitialIdentityServerPersistedGrantDbMigration -c PersistedGrantDbContext -o Data/Migrations/IdentityServer/PersistedGrantDb 2PM> update-database -c PersistedGrantDbContext3PM> add-migration InitialIdentityServerConfigurationDbMigration -c ConfigurationDbContext -o Data/Migrations/IdentityServer/ConfigurationDb4PM> update-database -c ConfigurationDbContext // 因为不用迁移用户数据,所以不用管用户上下文


整个过程没有报错,虽然它提示说可能造成数据丢失,但是并没有

图片


很流畅的就下来了,只是最后有一个小插曲,就是迁移好后,然后重新生成了容器镜像等,前端admin项目访问的时候,提示没有scope,后来发现Enabled为false了,不知什么时候被改了,修改为true就行了。

图片

除了这个小插曲,文末的问题才是最重要的,但是也是很简单的,不要慌,往下看就是了。



02

控制器API方面

既然我们的数据库表结构都变了,那控制器的一些API和视频模型肯定也会有变化的,这是肯定的,具体我就不好列举了,涵盖以下几个部分:

AccountController、ConsentController、DeviceController、GrantsController、这四部分。

图片

其实不要感觉更新的内容很多,都是很简单的几处,自己稍微看一看,或者用上边官方源代码覆盖下就好了。



03

视图部分

理所应当的,视图模型变了,那我们的页面也需要调整:

图片

就是这么多,对应修改下就行了。


整个过程大概持续了30~60分钟,全程并没有很难受的地方,都是粘贴复制啥的。只要心静就可快速搞定。


更新完成以后,可以看到项目已经没有问题了,但是这个时候还会剩下一个小知识点,看startup.cs就知道了。

图片




04
PART
配置源地址


如果你之前用过Ids4,肯定都知道那个梗,就是本地开发的时候一切正常,如果配置到服务器,源地址一直是localhost域名,之前我也写过一篇文章来讲如何处理这个问题,主要就是用到的是上边截图中,配置PublicOrigin这个属性即可,但是这次在4x版本中,这个api被删掉了。

如果你不做配置的话,会看到这个情况:

图片


找了很多资料,最后还是在官方开源项目的Issue中发现了,看来还是得多看Issue,可能官方也发现3x升级4x有很多问题,干脆直接Pinned了一个issue:

图片


最终的解决方案其实有两种,一种很简单,直接在中间件的最外层,也就是最上边,添加配置






 app.Use(async (ctx, next) => { ctx.SetIdentityServerOrigin("https://xxx.com"); await next(); });

其实就是SetIdentityServerOrigin方法。


第二种就稍微复杂了些,需要三步:

配置服务:








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
校验Token


果然不出意外,报错了,是在Admin项目发起登录,获取token后,一直刷新,不能获取资源服务器的API,一直401,解析token查看,缺少字段:

图片

大家可以看到,左侧迁移后的Token令牌竟然少了几个关键Claims,一定是哪里没有配置,

这里先大胆猜测下,我们能登录,证明用户系统没问题;

我们可以获取token,证明客户端Clients配置没问题;

但是一直401,缺少字段,那肯定是我们的资源服务确实对应的scope。


然后我各种检查,发现都是一样的数据,最后我想到了文章上边说到的官方除了增加几个字段以外,还增加了两个表,然后找了找资料,发现4x版本已经更新了,以前的时候,我们只需要针对客户端配置资源api就行了,比如这样:

图片

但是如果你看一下刚刚新建的数据库,可以发现ApiScopes表已经没有了ApiResources表的外键了,所以需要在新增的表ApiResourceScopes中进行配置:

图片


相当于做了一个跳板,当然你也可以说做了一个更复杂的关系表,因为这样的话,我们就可以针对一个资源服务器做多个Scope鉴权了,比如我们Blog.Core项目,我们可以分成好几个scope来鉴权,就像把一个资源服务器,拆成了多个一样,是不是又高级了!

到了这里,基本就已经迁移完成了,整个过程一个小时,当然你还需要部署什么的,也不难,我建议没有充裕的时间,还是用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